实体框架Include -我们可以有一个基于条件的.Include(p =>includeFiles == true ?

本文关键字:Include 框架 true includeFiles 条件 我们 有一个 实体 于条件 | 更新日期: 2023-09-27 17:50:33

是否有可能包含如下代码中使用的基于函数参数的工作。通过查看包含的MSDN文档,看起来这是不可能的。

public static Response<Person> GetById(int id, bool includeAddress = false
    , bool includeFiles = false
    , bool includeTags = false)
{
    var output = new Response<Person>();
    using (var dbContext = new SmartDataContext())
    {
        dbContext.Configuration.ProxyCreationEnabled = false;
        output.Entity = dbContext.EntityMasters.OfType<Person>()
            .Include(p => includeFiles == true ? p.FileMasters : null)
            .Include(p => includeAddress == true ? p.Addresses : null)
            .Include(p => includeTags == true ? p.Tags : null)
            .FirstOrDefault(e => e.EntityId == id);
    }
    return output;
}

是否有任何技巧可以直接处理它,或者我必须构建表达式代替。我甚至不确定如何为此构建一个表达式,而不是在dbContext中检查。我想如果我可以在进入dbContext作用域之前构建表达式。

我正在寻找的是在跳入USING语句之前解决所有条件。在下面的例子中,我创建了一个表达式并在USING

中使用它
public static Response<IEnumerable<ConfigurationType>> GetByAttributeType(int attributeType)
{
    Response<IEnumerable<ConfigurationType>> output = new Response<IEnumerable<ConfigurationType>>();
    System.Linq.Expressions.Expression<System.Func<ConfigurationType, bool>> expressions=null;
    switch (attributeType)
    {
        case 1:
            expressions = a => a.IsItemAttribute == true;
            break;
        case 2:
            expressions = a => a.IsReadPointAttribute == true;
            break;
        default:
            expressions = a => a.IsPersonAttribute == true;
            break;
    }

    using (var context = new SmartDataContext())
    {
        context.Configuration.ProxyCreationEnabled = false;
        output.Entity = context.ConfigurationTypes.Where(expressions).ToList();              
    }
    return output;
}

同样,我期望的是这样的东西。这听起来很奇怪,只是想太多,如果有一种方法来解决p。

IQueryable<Person> query = includeFiles?Include(p=>p.Files):null; //p is undefined
query.Append(includeTags?Include(p=>p.Tags):null);

我不确定这是否可能。如果没有,请帮助我了解原因。

实体框架Include -我们可以有一个基于条件的.Include(p =>includeFiles == true ?

逐条构建查询,有条件地调用Include。如果您想在using语句之外(和/或方法之外)使用逻辑执行此工作,您可以传递一个类型,该类型封装了用于应用必要的Include语句的逻辑。

例如:

public static Response<Person> GetById(int id, IIncludeConfiguration<Person> includeConfiguration = null)
{
    var output = new Response<Person>();
    using (var dbContext = new SmartDataContext())
    {
        dbContext.Configuration.ProxyCreationEnabled = false;
        var query = dbContext.EntityMasters.OfType<Person>();
        if(includeConfiguration != null)
        {
            query = includeConfiguration.ApplyIncludes(query);
        }
        output.Entity = query.FirstOrDefault(e => e.EntityId == id);
    }
    return output;
}
public interface IIncludeConfiguration<TEntity> where TEntity : class;
{
    IQueryable<TEntity> ApplyIncludes(IQueryable<TEntity> query)
}
public class PersonIncludeConfiguration : IIncludeConfiguration<Person>
{
    public bool IncludeFiles {get;set;}
    public bool IncludeAddresses {get;set;}
    ....

    public IQueryable<Person> ApplyIncludes(IQueryable<Person> query)
    {
        if(IncludeFiles) query = query.Include(x => x.FileMasters);
        if(IncludeAddresses) query = query.Include(x => x.Addresses);
        ....
        return query;
    }
GetById(1234, new PersonIncludeConfiguration{IncludeFiles = true});

你不能这样做,但你总是可以自己建立IQuerable。比如:

var queryable = dbContext.EntityMasters.OfType<Person>();
if (includeFiles)
{
    queryable = queryable.Include(p => p.FileMasters);
}