实体框架中的可空实体投影
时间:2020-03-06 14:47:33 来源:igfitidea点击:
我有以下SQL Server 2005数据库架构:
CREATE TABLE Messages ( MessageID int, Subject varchar(500), Text varchar(max) NULL, UserID NULL )
可以为空的" UserID"列是一个外键,并链接到该表
CREATE TABLE Users ( UserID int, ... )
现在,我有几个名称为Message,User等的POCO类,可在以下查询中使用:
public IList<Message> GetMessages(...) { var q = (from m in dataContext.Messages.Include("User") where ... select m); // could call ToList(), but... return (from m in q select new Message { ID = m.MessageID, User = new User { ID = m.User.UserID, FirstName = m.User.FirstName, ... } }).ToList(); }
现在注意,我建议使用Include(" Users")的实体框架加载与消息关联的用户(如果有)。另请注意,在第一个LINQ语句之后,我不调用ToList()。这样,仅从投影列表中指定的列(在这种情况下,将从数据库中返回MessageID,UserID,FirstName)。
这是问题所在,一旦Entity Framework遇到带有UserID == NULL的消息,它就会引发异常,原因是它无法转换为Int32,因为DB值为NULL。
如果我将最后两行更改为
return (from m in q select new Message { ID = m.MessageID, User = m.User == null ? null : new User { ID = m.User.UserID, ... } }).ToList()
然后抛出运行时NotSupportedException,表明它无法创建恒定的User类型,并且仅支持int,string,guid之类的原语。
除了在第一个语句之后立即实现结果并随后使用内存中的投影之外,还有人知道如何处理它吗?谢谢。
解决方案
我怀疑关系不是一对一的。
由于我们做了.Include(" Users")
,因此我们应该能够遍历Message
对象中的User
属性来获取所需的信息。
我们忘记了包含" Message"类的声明,但是我怀疑该类中的UserID属性未声明为可空类型。如果是这种情况,请将其从" int"更改为" int?"。 (可为null的int)。