EF从孩子递归到父母?

时间:2018-07-13 11:23:21

标签: entity-framework recursion tree

有什么方法可以从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查询,以使整个公司链从给定的子代一直延伸到父代遇到一个父代。特殊情况?还是我需要使用这样的循环?

1 个答案:

答案 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)来防止无限递归!