我需要使用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()
我收到错误消息:
“转换为值类型'System.Int32'失败,因为具体化值为null-结果类型的泛型参数或查询必须使用可空类型。”
我认为应该通过“.DefaultIfEmpty()”来解决这个问题。
如何解决此问题?
答案 0 :(得分:2)
需要使用Entity Framework
在C#项目中执行10个左连接
这是不太可能的。使用导航属性而不是连接在LINQ to Entities中表达查询几乎总是更好,更简单的方法。
相反,只需在导航属性中导航到项目相关值。
答案 1 :(得分:2)
@David Browne关于导航属性与EF中的连接是正确的。但是这里问题是不同的(与连接操作无关,但是处理结果)并且包含在异常消息中:
演员价值类型' System.Int32'失败,因为具体化值为空 - 结果类型的通用参数或查询必须使用可空类型。
这意味着投影(select
)试图从左外连接的一些右侧分配一个不可为空的类型值。在LINQ to Objects中,它将是一个简单的NullReferenceException
。但是,LINQ to Entities将查询转换为SQL,并且数据库(特别是SQL)对NULL
值具有自然支持,即使对于非可空列也是如此。因此EF能够成功执行SQL,但是当它需要实现结果(即将其放入匿名/特定类成员)时,db查询返回{{ 1}}虽然相应的属性是非可空类型,但是EF无法继续并且抛出异常,要求您通过将其转换为可为空的类型或将其转换为某个默认值等来解决它。 - 它取决于你,EF无法做出这个决定。
我要说null
有TableB
,你有这样的查询:
int Property
结果var query = from a in db.TableA
from b in db.TableB.Where(b => b.Key == a.Key).DefaultIfEmpty()
select new { Property = b.Property };
的C#隐含类型为Property
,因此当查询结果包含与int
不匹配的b
时,您将获得上述异常(a
从C#角度来看是b
,但从SQL端null
将是b.Property
。
为了解决它,您可以将其提升为可空类型:
NULL
或某些默认值
Property = (int?)b.Property
取决于您的需求。并对Property = b != null ? b.Property : 0
,int
,decimal
等任何非可空值类型执行类似操作。(DateTime
是引用类型,因此它没有此类问题(可以保留{ {1}}值))。