实体框架中的可空实体投影

时间:2008-09-26 15:44:34

标签: .net linq entity-framework

我有以下SQL Server 2005数据库架构:

CREATE TABLE Messages (
   MessageID int,
   Subject varchar(500),
   Text varchar(max) NULL,
   UserID NULL
)

列“UserID” - 可以为null - 是外键并链接到表

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(“用户”) - 加载与消息关联的用户(如果有)。另请注意,我没有在第一个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等原语。

除了在第一个语句之后实现结果并在之后使用内存中投影之外,任何人都知道如何处理它?感谢。

3 个答案:

答案 0 :(得分:2)

您忘记包含“Message”类的声明,但我怀疑该类中的UserID属性未声明为可空类型。如果是这种情况,请将其从“int”更改为“int?” (可以为空)。

答案 1 :(得分:0)

我怀疑你的关系不是1对1。

答案 2 :(得分:0)

由于您执行了.Include("Users"),因此您应该能够遍历User对象中的Message属性以获取所需的信息。