结合表达式而不是在Entity Framework中使用多个查询

Seb*_*ull 11 c# asp.net entity-framework iqueryable expression-trees

我有以下通用可查询(可能已经应用了选择):

IQueryable<TEntity> queryable = DBSet<TEntity>.AsQueryable();
Run Code Online (Sandbox Code Playgroud)

然后有Provider一个看起来像这样的类:

public class Provider<TEntity>
{
    public Expression<Func<TEntity, bool>> Condition { get; set; }

    [...]
}
Run Code Online (Sandbox Code Playgroud)

该Condition会每实例用以下方式进行定义:

Condition = entity => entity.Id == 3;
Run Code Online (Sandbox Code Playgroud)

现在我想选择至少由以下一个实体满足的所有Provider实例:ConditionDBSet

List<Provider> providers = [...];
var matchingProviders = providers.Where(provider => queryable.Any(provider.Condition))
Run Code Online (Sandbox Code Playgroud)

这个问题:我正在开始查询Provider列表中的每个实例.我宁愿使用单个查询来获得相同的结果.由于性能可疑,此主题尤其重要.如何使用单个查询获得相同的结果并使用Linq语句提高性能Expression Trees?

Iva*_*oev 5

有趣的挑战.我看到的唯一方法是构建动态UNION ALL查询,如下所示:

SELECT TOP 1 0 FROM Table WHERE Condition[0]
UNION ALL
SELECT TOP 1 1 FROM Table WHERE Condition[1]
...
UNION ALL
SELECT TOP 1 N-1 FROM Table WHERE Condition[N-1]
Run Code Online (Sandbox Code Playgroud)

然后使用返回的数字作为索引来获取匹配的提供程序.

像这样的东西:

var parameter = Expression.Parameter(typeof(TEntity), "e");
var indexQuery = providers
    .Select((provider, index) => queryable
        .Where(provider.Condition)
        .Take(1)
        .Select(Expression.Lambda<Func<TEntity, int>>(Expression.Constant(index), parameter)))
    .Aggregate(Queryable.Concat);

var indexes = indexQuery.ToList();
var matchingProviders = indexes.Select(index => providers[index]);
Run Code Online (Sandbox Code Playgroud)

请注意,我可能已经建立了查询,而无需使用Expression替换上面的类Select与

.Select(_ => index)
Run Code Online (Sandbox Code Playgroud)

但这会为每个索引引入不必要的SQL查询参数.