我有一个对象树,其大小可能是无限的。
实体类别具有其他类别实体作为子项。换句话说,一个类别可以有子类别:深度是无限的。
下面您可以看到我的实体的简化版本
public class ProductCategory : IEntity<ProductCategory>, IDeletable
{
public Guid ProductCategoryId { get; private set; }
public virtual ICollection<ProductCategory> Children { get; set; }
public virtual ProductCategory Father { get; set; }
}
我曾经懒得加载到几个小时前,所以我很容易得到孩子的孩子。
现在我已经禁用了延迟加载,因为我遇到了问题,我的查询是为了获得一个类别的子项。
public IEnumerable<ProductCategory> GetAllChildrenOfCategory(Guid categoryId)
{
var results = GetAllProductCategoriesQuery()
.Where(elt => elt.FatherId.Equals(categoryId))
.Include(elt => elt.Father)
.Include(elt => elt.Children);
return results.ToList().CloneEachElement();
}
我得到了该类别的所有孩子。但是,我没有孩子的孩子......
现在我有两个问题:
是否可以编写查询以便拥有整个类别树?
或者,是否可以配置实体框架,以便一旦从数据库中提取它,它总是会为您提供类别的子项,这样我就不必明确地包含导航属性?
其他选择......?
答案 0 :(得分:0)
据我所知,您可以使用字符串而不是lambda表达式来包含预先加载的属性。它不是很优雅,但它会给你一个解决方法:
1)找出你所拥有的最深层次,然后构建一个相应的包含字符串,例如&#34;父亲。父亲。&#34;并将其用于您的包含。我不能保证它有效,但我给它一个公平的机会。
2)首先在代码中,我不认为有这样的选择。它可能存在于EDMX中,但我完全不是这方面的专家。我建议你使用扩展方法来完成这项工作:
private static readonly queryStringForMaxDepth = WriteAMethodToFindIt();
public static IQueryable<ProductCategory> DeepProductCategories(this DbContext context){
return context.ProductCategories.Include(queryStringForMaxDepth);
}
您将能够使用如下:
context.DeepProductCategories()
.Where(...)
我希望这会给你一些想法。
答案 1 :(得分:0)
我之前通过使用MsSql中的视图完成了此操作。比我直接调用视图:
dbContext.Database.SqlQuery<ProductCategory>("select * from GetCategoryTree where RootCategoryId=1");
所以这给了我正是我想要的东西。所以它也是可查询的。 这是我使用的资源之一:sql recursive query parent child
Someone else asked For Recursive Queries before in msdn forums
答案 2 :(得分:0)
作为您问题的可能解决方案,我建议您使用Explicit Loading。这样,您可以在每次需要时从特定类别加载子类别:
var cat=context.FirstOrDefault(c=>c.ProductCategoryId ==categoryId);
// Load the subcategories related to a given category
context.Entry(cat).Collection(p => p.Children).Load();
答案 3 :(得分:0)
包括......
FatherRepository.All().Including(x => x.Childs, x => x.Childs.Select(y => y.ChildChild));
父班......
public class Father
{
public int Id { get; set; }
#region Navigations Properties
public virtual List<Child> Childs { get; set; }
#endregion
}
儿童班......
public class Child
{
public int Id { get; set; }
public int ChildChildId { get; set; }
public int FatherId { get; set; }
#region Navigations Properties
public virtual Father Father { get; set; }
public virtual ChildChild ChildChild { get; set; }
#endregion
}
ChildChild班级......
public class ChildChild
{
public int Id { get; set; }
}