C# 实体框架通用存储库,包括通过参数的属性

C# 实体框架通用存储库,包括通过参数的属性,c#,entity-framework,.net-core,C#,Entity Framework,.net Core,我在Entity Framework中实现了一个通用存储库,我正在尝试改进它,以使用EF提供的.Include(..)函数,而不是通过字符串包含导航属性,以便能够安全地重命名属性 以下是我目前的代码: public IQueryable<T> GetAll( Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryabl

我在Entity Framework中实现了一个通用存储库,我正在尝试改进它,以使用EF提供的.Include(..)函数,而不是通过字符串包含导航属性,以便能够安全地重命名属性

以下是我目前的代码:

public IQueryable<T> GetAll(
        Expression<Func<T, bool>> filter = null,
        Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<T> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query);
        }
        else
        {
            return query;
        }
    }
我的问题是:如何更改该方法,以便能够以以下方式(或类似方式)调用它:

受保护的内部IQueryable筛选器(表达式谓词,参数表达式[]includeProperties)
{
var query=RetrieveQuery();
if(谓词!=null)
{
query=query.Where(谓词).AsQueryable();
}
if(includeProperties!=null)
{
query=\u queryableUnitOfWork.ApplyIncludesOnQuery(查询,includeProperties);
}
返回(查询);
}
这个方法在那里调用

public IQueryable<TEntity> ApplyIncludesOnQuery<TEntity>(IQueryable<TEntity> query, params Expression<Func<TEntity, object>>[] includeProperties) where TEntity : class, IEntity
{
    // Return Applied Includes query
    return (includeProperties.Aggregate(query, (current, include) => current.Include(include)));
}
public IQueryable ApplyIncludesOnQuery(IQueryable查询,参数表达式[]includeProperties),其中tenty:class,ienty
{
//返回应用的包含查询
返回(includeProperties.Aggregate(查询,(当前,包括)=>current.include(包括));
}
筛选方法调用

 public IEnumerable<ShowStockProductDto> GetActiveShowStockProductListByProduct(int productId)
            {
                var foundedPStockroducts = Filter(
                    ent => ent.ProductId == productId && ent.IsActive,
                    ent => ent.StockProductPrices,
                    ent => ent.StockProductDepots,
                    ent => ent.StockProductSpecificationValues,
                    ent => ent.StockProductSpecificationValues.Select(spsv => spsv.SpecificationValue)
                    );

                // Map foundedPStockroducts to showStockProductList
                var showStockProductList = TypeAdapterFactory.Adapter.Adapt<IEnumerable<ShowStockProductDto>>(foundedPStockroducts).ToList();

                return (showStockProductList);
            }
public IEnumerable GetActiveShowStockProductListByProduct(int-productId)
{
var foundedpstockProducts=过滤器(
ent=>ent.ProductId==ProductId&&ent.IsActive,
ent=>ent.StockProductPrices,
ent=>ent.StockProductDepots,

ent=>ent.StockProductSpecificationValues,
ent=>ent.StockProductSpecificationValues.Select(spsv=>spsv.SpecificationValue) ); //将FoundedPStockProducts映射到showStockProductList var showStockProductList=TypeAdapterFactory.Adapter.Adapt(foundedpstockproducts.ToList(); 退货(showStockProductList); }
我建议您保留两个方法,一个接受字符串参数,一个表达式参数。存储库中的一些客户端可以更好地使用字符串签名,而其中一些客户端可以更好地使用表达式签名,这为它们带来了IntelliSense

public IQueryable<T> GetAll(params string[] including)
{
    var query = dbSet.AsQueryable();
    if (including != null)
        including.ToList().ForEach(include =>
        {
            if (!string.IsNullOrEmpty(include))
                query = query.Include(include);
        });
    return query;
}

public IQueryable<T> GetAll(params Expression<Func<T, object>>[] including)
{
    var query = dbSet.AsQueryable();
    if (including != null)
        including.ToList().ForEach(include =>
        {
            if (include != null)
                query = query.Include(include);
        });
    return query;
}

您可以使用
参数表达式[]includeProperties
代替字符串参数

public IQueryable<T> GetAll(
    Expression<Func<T, bool>> filter = null,
    Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
    params Expression<Func<T, object>>[] includeProperties)
{
    IQueryable<TEntity> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties)
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query);
        }
        else
        {
            return query;
        }
}
public IQueryable GetAll(
表达式筛选器=空,
Func orderBy=null,
参数表达式[]includeProperties)
{
IQueryable query=dbSet;
if(过滤器!=null)
{
query=query.Where(过滤器);
}
foreach(includeProperty中的var includeProperty)
{
query=query.Include(includeProperty);
}
if(orderBy!=null)
{
返回订单人(查询);
}
其他的
{
返回查询;
}
}

几天前,我在自己的项目中正在处理这件事,是的,我对回答stackoverflow的问题是新手,我非常欢迎:/@NaDeR Star为什么需要下面两行:ent=>ent.StockProductSpecificationValues,ent=>ent.StockProductSpecificationValues.Select(spsv=>spsv.SpecificationValue)其中包括StockProductSpecificationValues Clollectionent=>ent的SpecificationValue导航属性。StockProductSpecificationValues是一个集合,而ent=>ent.StockProductSpecificationValues.Select(spsv=>spsv.SpecificationValue)是一个导航,如何从列表中包含子属性。例如:includeProperties:u=>u.Addresses.Select(a=>a.State.Country)应该为用户拉取地址列表,每个用户都填充了状态,但是它会抛出一个错误
 public IEnumerable<ShowStockProductDto> GetActiveShowStockProductListByProduct(int productId)
            {
                var foundedPStockroducts = Filter(
                    ent => ent.ProductId == productId && ent.IsActive,
                    ent => ent.StockProductPrices,
                    ent => ent.StockProductDepots,
                    ent => ent.StockProductSpecificationValues,
                    ent => ent.StockProductSpecificationValues.Select(spsv => spsv.SpecificationValue)
                    );

                // Map foundedPStockroducts to showStockProductList
                var showStockProductList = TypeAdapterFactory.Adapter.Adapt<IEnumerable<ShowStockProductDto>>(foundedPStockroducts).ToList();

                return (showStockProductList);
            }
public IQueryable<T> GetAll(params string[] including)
{
    var query = dbSet.AsQueryable();
    if (including != null)
        including.ToList().ForEach(include =>
        {
            if (!string.IsNullOrEmpty(include))
                query = query.Include(include);
        });
    return query;
}

public IQueryable<T> GetAll(params Expression<Func<T, object>>[] including)
{
    var query = dbSet.AsQueryable();
    if (including != null)
        including.ToList().ForEach(include =>
        {
            if (include != null)
                query = query.Include(include);
        });
    return query;
}
var result1 = schoolRepository.GetAll("Students", "Teachers");
var result2 = schoolRepository.GetAll(x=>x.Students, x=>x.Teachers);
public IQueryable<T> GetAll(
    Expression<Func<T, bool>> filter = null,
    Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
    params Expression<Func<T, object>>[] includeProperties)
{
    IQueryable<TEntity> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties)
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query);
        }
        else
        {
            return query;
        }
}