C# 基于空值的实体框架中的左连接

C# 基于空值的实体框架中的左连接,c#,entity-framework,C#,Entity Framework,我需要使用实体框架在C项目中执行10个左连接。我已经检查了至少10个不同的页面和stackoverflow帖子,了解如何执行此操作。他们都没有工作 我当前的连接如下所示: from tbl1 in context.tblName1 join varOne in context.tblName2 on tbl1.paramOne equals varOne.paramOne into j1 from jResOne in j1.DefaultIfEmpty() var query = from

我需要使用实体框架在C项目中执行10个左连接。我已经检查了至少10个不同的页面和stackoverflow帖子,了解如何执行此操作。他们都没有工作

我当前的连接如下所示:

from tbl1 in context.tblName1
join varOne in context.tblName2 on tbl1.paramOne equals varOne.paramOne into j1
from jResOne in j1.DefaultIfEmpty()
var query = from a in db.TableA
            from b in db.TableB.Where(b => b.Key == a.Key).DefaultIfEmpty()
            select new { Property = b.Property };
我收到错误消息:

转换为值类型“System.Int32”失败,因为具体化的值为null-结果类型的泛型参数或查询必须使用可为null的类型

我认为应该由.DefaultIfEmpty解决

我如何解决这个问题

需要使用实体框架在C项目中执行10个左连接

这是极不可能的。几乎总是有更好、更简单的方法使用导航属性(而不是联接)将LINQ中的查询表示为实体


相反,只需在导航属性之间导航到与项目相关的值。

@David Browne关于导航属性与加入EF的关系是正确的。但这里的问题与连接操作不同,与处理结果无关,并且包含在异常消息中:

转换为值类型“System.Int32”失败,因为具体化的值为null-结果类型的泛型参数或查询必须使用可为null的类型

这意味着投影选择正在尝试从左外部联接的某些右侧指定一个不可为null的类型值。在LINQ to对象中,这将是一个简单的NullReferenceException。然而,LINQtoEntities将查询转换为SQL,数据库和SQL尤其支持空值,即使是不可空的列。因此EF能够成功地执行SQL,但当它需要具体化结果时,即将其放入匿名/特定类成员中,db查询返回null,而相应的属性为不可为null的类型,EF无法继续,正在抛出异常,要求您通过将其强制转换为可为null的类型或将其转换为某个默认值等方式来解决此问题。这取决于您,EF无法做出此决定

假设TableB有int属性,您有如下查询:

from tbl1 in context.tblName1
join varOne in context.tblName2 on tbl1.paramOne equals varOne.paramOne into j1
from jResOne in j1.DefaultIfEmpty()
var query = from a in db.TableA
            from b in db.TableB.Where(b => b.Key == a.Key).DefaultIfEmpty()
            select new { Property = b.Property };
result属性的C隐含类型是int,因此当查询结果包含与a不匹配的b时,您将得到上述异常。从C的角度来看,b将为null,但从SQL的角度来看,b.Property将为null

为了解决此问题,可以将其升级为可为null的类型:

Property = (int?)b.Property
或者设置为某个默认值

Property =  b != null ? b.Property : 0

根据你的需要。对于任何不可为null的值类型,如int、decimal、DateTime等,也要执行类似操作。string是一种引用类型,因此它没有这样的问题,可以保存null值。

异常不能来自连接,而是来自某些投影/聚合。检查查询的其他部分。并考虑使用当前回答中建议的导航属性。@ IvanStoev,您是正确的。在select子句中,我需要一个VarName=tblRowVar==null?0:tblRowVar.rowParam,这解决了我的问题,请为我的问题添加一个答案,以便我可以选择它作为答案,如果您愿意的话。