在实体框架中筛选子实体的最佳方法
本文关键字:实体 最佳 方法 筛选 框架 | 更新日期: 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"的方法来做到这一点(比如某种"按层次类型"结构,也许?),但我只是觉得这至少有助于简化查询。
希望能有所帮助!)