有什么方法可以从EF获取一个实体链,该实体链表示从Child一直到自引用层次结构中的根Parent实体的链?我当然可以使用while循环来做到这一点,例如:
var chain = new List<Node>();
var thisNode = db.Nodes.First(n => n.Id == [whatever]);
do {
chain.Add(thisNode);
thisNode = thisNode.ParentId == null ? null : thisNode.Parent;
} while (thisNode != null);
但是我认为这将导致对层次结构中每个级别的数据库查询一次。虽然我们在这里谈论的是公认的很小的性能提升,但有没有一种方法可以将我的逻辑表达为单个LINQ查询,以使整个公司链从给定的子代一直延伸到父代遇到一个父代。特殊情况?还是我需要使用这样的循环?
答案 0 :(得分:0)
也许这是一个“骗子”的答案,但是我实际上通过出色的AutoMapper实现了我想要的。我想这是幕后花絮,它正在为我做递归工作。我的EF实体具有Parent
导航属性,我要映射的DTO看起来像这样:
public class CompanyInChainDTO
{
public Guid Id { get; set; }
public string Name { get; set; }
public CompanyInChainDTO Parent { get; set; }
}
...,并且此代码使AutoMapper从具有给定ID的子代到根父代(即没有Parent
的子代)创建DTO链:
Mapper.Initialize(conf =>
{
conf.CreateMap<EF.Company, CompanyInChainDTO>().MaxDepth(100);
});
using (var context = new EfContext())
{
var child = context.Companies.First(comp => comp.Id == [whatever]);
CompanyInChainDTO childDto = Mapper.Map<CompanyInChainDTO>(child);
return childDto; // Returns the child DTO with full Child -> Parent chain!
}
非常酷-默认情况下,我不知道AutoMapper遵循EF导航属性。请注意,在没有根母公司的情况下,为了安全起见,我还使用MaxDepth(100)
来防止无限递归!