使用内联对象初始化器与将变量 1 传递给 EF Select 的细微差别



将Func 另存为变量,然后将其传递给实体框架选择与在选择中内联键入转换有什么区别。

Func<Models.Contact,ViewModels.Contact> ToViewModel = 
c => new ViewModels.Contact()
{
ID = c.ID,
...
UserName = c.User.UserName
};
...
return dc.Contacts.Select(ToViewModel);

而不是

return dc.Contacts.Select(c => new ViewModels.Contact()
{
ID = c.ID,
...
UserName = c.User.UserName
});

我问这个是因为尽管这两种方法都有效,但它们对空值和其他一些事情的反应略有不同,我不明白为什么。

例如,在这种情况下,联系人可能有也可能没有用户,因此用户可能为空,也可能不为空。当内联键入初始化器时,它将使属性正常失败为 null。但是,当通过变量传递相同的初始值设定项时,它将抛出 NullReferenceException。

这是为什么呢?

请注意,我想保存初始化器的原因是,它可以在每个 CRUD 操作中重用,以便从 WebAPI 返回对象。必须在类周围复制和粘贴选择会很烦人,特别是如果随着时间的推移需要在响应中添加或删除属性。

第二个示例编译为 EF 在服务器上运行的Expression<Func<Contact, Contact>>。 (使用IQueryable界面)
它变成一个使用 OUTER JOIN 的 SQL 查询,该查询不会生成空引用异常。

您的第一个示例不是表达式树,因此它通过IEnumerable<T>接口并在客户端上执行。
您可以通过将ToViewModel更改为Expression<Func<...>>来使其行为与第一个示例相同。

最新更新