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是唯一可用的选项)。我无法检查匿名类型的解决方案,但我相信解决方案会奏效:)。是的,会的,我测试了它以确定:)