Linq 投影:获取新投影实体的参考
Posted
技术标签:
【中文标题】Linq 投影:获取新投影实体的参考【英文标题】:Linq projection: Get reference of new projected entity 【发布时间】:2015-12-25 17:41:28 【问题描述】:我需要将 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();
【问题讨论】:
【参考方案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();
【讨论】:
【参考方案2】:在常规 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
s,然后遍历parent.Children
集合并将它们的Parent
分配给它们(如Ufuk 的回答)。
【讨论】:
以上是关于Linq 投影:获取新投影实体的参考的主要内容,如果未能解决你的问题,请参考以下文章