EF Core 2.0包含具有动态查询的嵌套实体

时间:2018-01-01 03:41:50

标签: c# .net-core entity-framework-core

我使用System.Linq.Dynamic.Core;和以下扩展方法按名称动态访问DbSet并从字符串生成查询。

这是extesion方法:

namespace Microsoft.EntityFrameworkCore
{
    public static partial class CustomExtensions
    {
        public static IQueryable Query(this DbContext context, string entityName) =>
            context.Query(context.Model.FindEntityType(entityName).ClrType);

        public static IQueryable Query(this DbContext context, Type entityType) =>
            (IQueryable)((IDbSetCache)context).GetOrAddSet(context.GetDependencies().SetSource, entityType);
    }
}

这是我访问DbSet的方式:

IQueryable<T> dbSet = (IQueryable<T>)_db.Query(entityName);

这很好用,我可以构建一个查询,然后创建一个列表,但没有嵌套实体加载。似乎IQueryable没有Include()的定义。如果我以正常方式直接访问db上下文但不使用这种动态方法,我可以看到include方法。

如何使用动态方法包含嵌套实体?

2 个答案:

答案 0 :(得分:4)

首先,您正在使用GetOrAddSet

IDbSetCache
public interface IDbSetCache
     

//       //摘要:       //此API支持实体框架核心基础结构,不适用       //直接从你的代码中使用此API可能会在以后更改或删除

IncludeIQueryable<TEntity>EntityFrameworkQueryableExtensions的{​​{1}}方法,不是Microsoft.EntityFrameworkCore。您的函数返回IQueryable

我建议你创建如下的扩展方法,

IQueryable

你可以消费,

        public static IQueryable<T> MyQuery<T>(this DbContext context)
            where T : class
        {
            return context.Set<T>().AsQueryable();
        }

对于动态包含,

  var result = _dbContext.MyQuery<Employee>().Include("Department");

答案 1 :(得分:2)

我有一个解决此问题的邮政编码。我使用表达式树。

我的实体模型如下:

public class PortfolioTechnology
{
    public int PortfolioId { get; set; }
    public Portfolio Portfolio { get; set; }

    public int TechnologyId { get; set; }
    public Technology Technology { get; set; }
}

我的主要代码如下:

public SharpListResponse<PortfolioTechnology> GetAll(
    Expression<Func<PortfolioTechnology, bool>> predicate,
    params Expression<Func<PortfolioTechnology,object>>[] includes)
{
    var query = _dbContext.PortfolioTechnology.AsQueryable();

    foreach (var include in includes)
    {
        var memberExpression = include.Body as MemberExpression;

        if (memberExpression != null)
            query = query.Include(memberExpression.Member.Name);
    }

    var result = query.Where(predicate).ToList();

    return new SharpListResponse<PortfolioTechnology>(result);
}

并使用这种方法,如下所示:

var list = _unitOfWork.PortfolioTechnologyRepository.GetAll(x => x.PortfolioId == id, 
                                                            y => y.Technology);

如果要包括多个实体,例如包括投资组合和技术实体,则代码如下:

 var list = _unitOfWork.PortfolioTechnologyRepository.GetAll(x => x.PortfolioId == id, 
                                                             y => y.Technology,
                                                             x => x.Portfolio);

注意: SharpListResponse 是包装器类。 没有它的代码就可以工作

SharpListResponse的更多详细信息:https://www.nuget.org/packages/SharpRequestResponseWrapper/