【问题标题】:How to filter by fields from navigation properties in Entity Framework?如何从实体框架中的导航属性中按字段进行过滤?
【发布时间】:2016-01-29 14:50:08
【问题描述】:

我有这样的课程:

public class ProductInCategory
{
    public Guid Guid { get; set; }
    public long ProductID { get; set; }
    public long ProductCategoryID { get; set; }

    public virtual Product Product { get; set; }
    public virtual ProductCategory ProductCategory { get; set; }
}

public class Product
{
    public virtual ICollection<ProductInCategory> ProductsInCategories { get; set; }

    // and other fields and navigation properties not important for this example
}

现在我想执行查询,该查询使用实体框架获取所有产品,并使用特定的 ProductCategoryID 进行预加载:

using (var db = new EntityDataModel())
{
    var node = db.Tree.FirstOrDefault(x => x.Guid == editedNode);
    List<long> descentantIds = db.Tree
                              .Where(x => x.AncestorID == node.AncestorID)
                              .Select(x => x.DescendantID).ToList();

    List<Product> products = db.Products
        .Include("Details")
        .Include("Prices")
        .Include("Prices.Currency")
        .Include("Prices.Seller")
        .Include("Translations")
        .Include("Translations.Language")
        .Include("ProductsInCategories")
        .Where(x => ... )) // how to filter by ProductsInCategories.ProductCategoryID (which in my case is descentantIds) ? 
        .ToList();
}

我认为我应该在 Where 子句中输入类似于 .Where(x =&gt; descentantIds.Contains(x.ProductsInCategories.ProductCategoryID)) 的内容,但这不起作用。

Here 是类似的解决方案,但我不知道如何在我的情况下应用它。

感谢您的建议!

【问题讨论】:

  • 你到底想要什么?该descentantIds 包含ProductsInCategories 中的任何ID?全部?反过来呢?
  • 我想实现相当于 SQL WHERE ProductsInCategories.ProductCategoryID IN (1, 2, 3 .. n) ,但我看不到如何通过导航属性 ProductsInCategories 中 ProductCategoryID 的 lambda 表达式值获得。在我的情况下,声明是 IQueryable&lt;Product&gt;
  • ProductionCategories 是产品的 ICollection,您想要哪个 ProductCategoryID?

标签: c# entity-framework linq navigation-properties


【解决方案1】:

试试这个

 .SelectMany(x => x.ProductsInCategories.Where(c => descentantIds.Contains(c.ProductCategoryID))).Select(c => c.Product).Distinct()

【讨论】:

    【解决方案2】:

    虽然@mariovalens 提供了解决我的问题的可行解决方案,但我找到了另一个解决方案。我正在粘贴它们。它可能对其他人有帮助;)

    请注意,为了正确加载,在 SelectMany()、Select()、Where() 等过滤方法之后插入 .Include() 方法。在这些方法之前输入 .Include() 将在导航属性中返回空值。

    using (var db = new EntityDataModel())
    {
        var node = db.Tree.FirstOrDefault(x => x.Guid == editedNode);
        List<long> descentantIds = db.Tree
                   .Where(x => x.AncestorID == node.AncestorID)
                   .Select(x => x.DescendantID)
                   .ToList();
    
        List<Product> method1 = db.Products
            .SelectMany(x => x.ProductsInCategories.Where(c => descentantIds.Contains(c.ProductCategoryID))).Select(c => c.Product).Distinct()
            .Include(c => c.Assets.Select(c1 => c1.Translations.Select(c2 => c2.Language)))
            .Include(c => c.Tags.Select(c1 => c1.Translations.Select(c2 => c2.Language)))
            .Include(c => c.Details)
            .Include(c => c.Prices.Select(c1 => c1.Currency))
            .Include(c => c.Prices.Select(c1 => c1.Seller))
            .Include(c => c.Translations.Select(c1 => c1.Language))
            .Include(c => c.ProductsInCategories)
            .ToList();
    
        var method2 = (from product in db.Products
                     join productsInCategories in db.ProductsInCategories
                     on product.ID equals productsInCategories.ProductID
                     join productsCategories in db.ProductsCategories
                     on productsInCategories.ProductCategoryID equals productsCategories.ID
                     where descentantIds.Contains(productsInCategories.ProductCategoryID)
                     select product)
                     .Include(c => c.Assets.Select(c1 => c1.Translations.Select(c2 => c2.Language)))
                     .Include(c => c.Tags.Select(c1 => c1.Translations.Select(c2 => c2.Language)))
                     .Include(c => c.Details)
                     .Include(c => c.Prices.Select(c1 => c1.Currency))
                     .Include(c => c.Prices.Select(c1 => c1.Seller))
                     .Include(c => c.Translations.Select(c1 => c1.Language))
                     .Include(c => c.ProductsInCategories);
    
        var result = method2.ToList<Product>();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      相关资源
      最近更新 更多