在实体框架中筛选子实体的最佳方法

本文关键字:实体 最佳 方法 筛选 框架 | 更新日期: 2023-09-27 18:21:06

我没有删除实体。我只是用IsDeleted属性签名。问题是,当我得到一个父元素时,即使IsDeleted属性为true或false,它的所有子元素都会被加载。然后我做了下面这样的事情,但我想知道有更好的方法吗?

var result = from p in context.Set<Product>().Include(x => x.Reviews)
                        select new
                             {
                                 Product = x,
                                 ProductReviews = x.ProductReviews.Where(y => !y.IsDeleted)
                             };
 var products = new List<Product>();
            foreach (var product in result.OrderBy(x => x.Product.Id).Skip(skipRecords).Take(pageSize))
            {
                var p = new Product();
                p = product.Product;
                p.ProductReviews = product.ProductReviews.ToList();
                products.Add(p);
            }
return products;

如何改进此代码块?

感谢

在实体框架中筛选子实体的最佳方法

我之前为解决这种情况所做的是创建一个特定的接口,表示像这样"标记删除"的类,然后创建一个过滤掉它们的扩展方法。

如果只有一个具有IsDeleted属性的类,则不需要单独的接口,只需使用该类即可。但我暂时假设您确实有多个类,并且需要接口。

因此接口的定义如下:

public interface IHaveIsDeleted
{
  public bool IsDeleted { get; set; }
}

然后,我的扩展方法将被定义在一个静态类中,如下所示:

public static class MyExtensionMethods
{
  public IQueryable<T> FilterDeleted(this IQueryable<T> src) where T : IHaveIsDeleted
  {
    return src.Where(x => !x.IsDeleted);
  }
}

因为这是在IQueryable<T>上完成的,所以where子句会被构建到发送到数据库的查询中,因此不会返回任何IsDeleted为true的记录。因此,在您的示例中,您所要做的就是调用x.ProductReviews.FilterDeleted()

现在,我使用这个方法的项目实际上是使用LINQ2SQL。我自己对EF还很陌生,所以可能有一种更"特定于EF"的方法来做到这一点(比如某种"按层次类型"结构,也许?),但我只是觉得这至少有助于简化查询。

希望能有所帮助!)