C# 内联使用对象初始化器与将变量1传递给EF Select之间的细微差别
将Func保存为变量,然后将其传递给实体框架select,与在select中内联键入转换有什么区别C# 内联使用对象初始化器与将变量1传递给EF Select之间的细微差别,c#,entity-framework,C#,Entity Framework,将Func保存为变量,然后将其传递给实体框架select,与在select中内联键入转换有什么区别 Func<Models.Contact,ViewModels.Contact> ToViewModel = c => new ViewModels.Contact() { ID = c.ID, ... UserName = c.User.UserName }; ... return dc.Contact
Func<Models.Contact,ViewModels.Contact> ToViewModel =
c => new ViewModels.Contact()
{
ID = c.ID,
...
UserName = c.User.UserName
};
...
return dc.Contacts.Select(ToViewModel);
我这样问是因为尽管这两种方法都有效,但它们对null和其他一些东西的反应却有细微的不同,我不明白为什么
例如,在这种情况下,联系人可能有用户,也可能没有用户,因此用户可能为空,也可能不为空。在内联输入初始化器时,它将使属性正常地失败为null。但是,当通过变量传递相同的初始值设定项时,它将抛出NullReferenceException
为什么会这样
请注意,我希望保存初始化器的原因是,它可以在每个CRUD操作中重用,以便从WebApi返回对象。必须在类周围复制和粘贴select,这会很烦人,特别是当需要在响应中添加或删除属性时。您的第二个示例编译为一个表达式,EF在服务器上运行。(使用
IQueryable
界面)它变成了一个使用外部联接的SQL查询,外部联接不会生成空引用异常 您的第一个示例不是表达式树,因此它通过
IEnumerable
接口并在客户机上执行。通过将
ToViewModel
更改为Expression
可以使其行为与第一个示例相同。第二个示例编译为Expression
,EF在服务器上运行。(使用IQueryable
界面)它变成了一个使用外部联接的SQL查询,外部联接不会生成空引用异常 您的第一个示例不是表达式树,因此它通过
IEnumerable
接口并在客户机上执行。通过将
ToViewModel
更改为表达式,可以使其行为与第一个示例相同
return dc.Contacts.Select(c => new ViewModels.Contact()
{
ID = c.ID,
...
UserName = c.User.UserName
});