EFCore 附加"calculated properties"的最佳方式



假设我有一个表Mail和一个表Mail.Read,其中存储了邮件和读取邮件的用户之间的关系。

现在我的邮件实体有一个未绑定的属性DateTime? dateRead,是否有可能以某种方式加入这个属性,保持IQueryable<Mail>?

from m in dbContext.Mails
from mr in dbContext.MailsRead.Where(mr => mr.MailId = m.Id && mr.UserId == UserId).DefaultIfEmpty()
select new { Mail = m, Seen = (DateTime?)mr.DateCreated }

工作,但给了我一个新的类型,所以结果不能在IQueryable<Mail>中传递。我想以某种方式设置未绑定属性,以保持纯可查询。

例如

(from m in dbContext.Mails
from mr in dbContext.MailsRead.Where(mr => mr.MailId = m.Id && mr.UserId == UserId).DefaultIfEmpty()
select new { Mail = m, Seen = (DateTime?)mr.DateCreated })
.Select(m => { m.DateSeen = m.Seen; return m.Mail; });

设置属性,同时仍然是IQueryable。由于EFCore无法处理此查询,因此在此解决方案之后,过滤器(例如.Where())不再可行。

如果实体使用正确的关系,并且MailRead实体在Mail中显示为List<MailRead> MailsRead属性:

class Mail
{
public long Id {get;set;}
...
public List<MailRead> MailsRead {get;set;}
...
}

你可以这样写:

var mails=dbContext.Mails.Inculde(m=>m.MailsRead
.Where(mr=>mr.UserID == UserID);

filter include是在EF Core 5中首次引入的。

如果实体没有关系,它们应该有关系。EF Core是一个ORM。DbContext不是数据库的模型,实体不是表,LINQ不是SQL的替代品。顾名思义,EF Core将对象映射到关系类型。这意味着允许应用程序使用对象并将任何操作映射到SQL。

最新更新