C# 从join映射-类型';CarDTO&x27;出现在单个LINQ to Entities查询中的两个结构不兼容的初始化中
我试图从C# 从join映射-类型';CarDTO&x27;出现在单个LINQ to Entities查询中的两个结构不兼容的初始化中,c#,entity-framework,linq,linq-to-entities,C#,Entity Framework,Linq,Linq To Entities,我试图从左连接的右侧映射到CarDTO,但出现以下错误: “CarDTO”类型出现在两种结构不兼容的类型中 在单个LINQ到实体查询中进行初始化。类型可以是 在同一查询中的两个位置初始化,但仅当 属性在两个位置都设置,并且这些属性在 同样的顺序 我正在尝试进行自左连接,我的查询如下所示: var query = from left in db.Cars join right in db.Cars on left.id_Base equals right.ID into rightGrou
左连接的右侧映射到CarDTO
,但出现以下错误:
“CarDTO”类型出现在两种结构不兼容的类型中
在单个LINQ到实体查询中进行初始化。类型可以是
在同一查询中的两个位置初始化,但仅当
属性在两个位置都设置,并且这些属性在
同样的顺序
我正在尝试进行自左连接
,我的查询如下所示:
var query = from left in db.Cars
join right in db.Cars on left.id_Base equals right.ID into rightGrouped
from rightGr in rightGrouped.DefaultIfEmpty()
select new CarDTO()
{
ID = left.ID,
Description = left.DisplayName,
Name = left.Name,
IsSystem = left != null ? left.Template.isSystem : (byte?)null,
IdBase = left.id_Base,
InnerCar = new CarDTO()
{
ID = rightGr.ID,
Description = rightGr.DisplayName,
Name = rightGr.Name,
IsSystem = rightGr != null ? rightGr.Template.isSystem : (byte?)null,
IdBase = rightGr.id_Base,
InnerCar = new CarDTO()
}
};
如果我将以下行InnerCar=new CarDTO()
更改为InnerCar=null
,
然后我得到以下错误:
无法创建类型为“CarDTO”的空常量值。唯一实体
此类型中支持类型、枚举类型或基元类型
上下文`
有人知道我做错了什么吗?错误消息解释说,EF希望同一表达式中相同类型的所有初始化(CarDto
)遵循一条规则:在每次初始化中,应按相同的顺序设置相同的属性。您的代码违反了此规则,因为您有3次初始化。其中两个按相同顺序设置相同的属性,但第三个(最后一个InnerCar=new CarDTO()
)没有设置
在InnerCar.InnerCar
初始化中满足此规则的唯一可能值是null
(因为递归定义)。但是,EF不允许您这样做,因为它不能创建任意类型的常量值(不知道如何将此类内容转换为SQL)
因此,使用递归类型执行此操作是不可能的。相反,我们应该为InnerCar
使用不同的类型。例如,可以使用匿名类型执行此操作:
select new
{
ID = left.ID,
Description = left.DisplayName,
Name = left.Name,
IsSystem = left != null ? left.Template.isSystem : (byte?)null,
IdBase = left.id_Base,
InnerCar = new
{
ID = rightGr.ID,
Description = rightGr.DisplayName,
Name = rightGr.Name,
IsSystem = rightGr != null ? rightGr.Template.isSystem : (byte?)null,
IdBase = rightGr.id_Base
}
};
这将起作用,因为这里有两种匿名类型不同。第一个有6个属性(包括InnerCar
),第二个有5个属性(没有InnerCar
)。当然,这里不要求类型是匿名的
您也可以将此结构展平:
select new
{
LeftID = left.ID,
RightID = rightGr.ID,
// etc
};
在执行此类映射并完成任何其他筛选\paging\whatever之后,请在具体化后将其转换为您的类型:
// query here is complete
var result = query.AsEnumerable().Select(c => {
new CarDto {
ID = c.ID,
Description = c.Description,
// etc
}
});
尝试将最后一行中的InnerCar=new CarDTO()
更改为InnerCar=null
。@Evk感谢您的建议,但我收到一个错误无法创建“CarDTO”类型的null常量值。在此上下文中只支持实体类型、枚举类型或基元类型。
似乎除了为InnerCar
使用不同的类型之外没有其他方法(例如使用匿名类型)。@Evk您如何得出此结论?EF需要相同类型的所有初始化(CarDto
)相同(相同的属性以相同的顺序设置),但您不能在此处执行此操作,因为您必须将InnerCar
的InnerCar
设置为某个值,但EF不允许将其设置为null(并且null是唯一可用的选项)。我无法检查匿名类型的解决方案,但我相信解决方案会奏效:)。是的,会的,我测试了它以确定:)