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

时间:2015-09-28 13:03:30

标签: entity-framework linq linq-to-entities entity-framework-6

我需要将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();
}

2 个答案:

答案 0 :(得分:1)

您必须使用变量,但不能在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();
}

答案 1 :(得分:1)

在常规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中创建对象的机制完全不同,但初始化 logic 可以被认为是相同的,并且适用相同的限制。

如您所知,在LINQ-to-Entities中,我们不能在查询表达式中调用实体的实例方法。例如,你可以在Parent中调用一些构造其子元素的方法(并将其作为父元素分配给它)。就像现在一样,你唯一能做的就是先用嵌套的Parent构建parent.Children s,然后遍历parent.Children个集合,并将Parent分配给class B(A): def __init__(self, v, v2): # Do some processing super(B, self).__init__(v, v2) 他们(如在Ufuk的回答中)。

相关问题