Linq 投影:获取新投影实体的参考

Linq projection: Get reference of new projected entity

我需要将 EF 实体映射到相应的 DTO。在下面的示例中,我有 EF 实体 Parent 和 Child,而 Child 实体包含对 Parent 对象的引用。我还有 ParentDto 和 ChildDto (DTO),并且 ChildDto 包含对 ParentDto(不是 Parent)的引用。那么,如何在以下方法中将 ParentDto 引用分配给 ChildDto 实例:

public Task<List<ParentDto>> Method()
{
    return (Context.Set<Parent>()
        .Where(someCondition)
        .Select(p => new ParentDto
        {
            // here we map all properties from Parent to ParentDto
            ... ,
            Children = p.Children.Select(c => new ChildDto
            {
                // here we map all properties from Child to ChildDto
                ... ,
                Parent = ? // reference to newly created ParentDto instance
            })
        }).ToListAsync();
}

您必须使用变量,但不能在 lambda 表达式中使用。调用 ToListAsync():

后必须在内存中进行映射
public Task<List<ParentDto>> Method()
{
    var parents = await (Context.Set<Parent>()
                                .Where(someCondition)
                                .ToListAsync());
    return parents.Select(p =>
    {
        var parent = new ParentDto();
        //map parent properties
        parent.Children = p.Children.Select(c => new ChildrenDto 
        {
            //map child properties
        });
       return parent;
    }).ToList();
}

在常规 LINQ(不是实体)中这是不可能的,因为对象初始值设定项的一个重要特征:原子分配。如您所见,here,对象初始化如...

var c = new Customer() { Name = "Bart", City = "Redmond", Age = 24 };

...等同于...

Customer __t = new Customer();
__t.Name = "Bart";
__t.City = "Redmond";
__t.Age = 24;
Customer c = __t;

因此首先创建并完全初始化对象,然后公开其引用。因此,如果在对象内部初始化了另一个对象,则嵌套对象将永远无法在初始化阶段获取对其父对象的引用。您只能在之后分配父对象。

尽管在 LINQ-to-entities 中创建对象的机制完全不同,初始化 逻辑 可以被认为是相同的,并且适用相同的限制。

如您所知,在 LINQ-to-Entities 中,我们无法在查询表达式中调用实体的实例方法。否则,例如,您可以在 Parent 中调用一些方法来构造其子项(并将自己分配给它作为它们的父项)。就像现在一样,你唯一能做的就是先用嵌套的 parent.Children 构造 Parent,然后遍历 parent.Children 集合并将它们的 Parent 分配给他们(如 Ufuk 的回答)。