实体框架对LINQ表达式的翻译(动态条件错误)

问题描述 投票:0回答:1

在使用涉及动态条件的方法时,实体框架将 LINQ 表达式转换为 SQL 查询时遇到问题

    public static IEnumerable<KeyValuePair<TKey, TValue>> GetKeyValueAsync<TEntity, TKey, TValue>
    (
        this IQueryable<TEntity> queryable,
        KeyValueFilters<TKey?> filters,
        Expression<Func<TEntity, TKey>> keySelector,
        Expression<Func<TEntity, TValue>> valueSelector
    )
    {
        var term = filters.Term?.ToLower().Trim();
        var id = filters.Id;

        var keyCompliled = keySelector.Compile();
        var valueCompliled = valueSelector.Compile();

        var query = queryable
            .Select(x => new
            {
                Key = keyCompliled.Invoke(x),
                Value = valueCompliled.Invoke(x)
            })

            .WhereIf(id != null && string.IsNullOrEmpty(term), x => x.Key!.ToString() == id!.ToString())
            .WhereIf(!string.IsNullOrEmpty(term), x => x.Value!.ToString()!.ToLower().Contains(term!))

            .Take(5)
            .ToList();

        var data = query.Select(x => new KeyValuePair<TKey, TValue>(x.Key, x.Value));

        return data;
    }

执行上述代码时遇到以下错误:

The LINQ expression 'DbSet<SubscriptionType>()
    .Where(s => __ef_filter__p_0 || !(EF.Property<bool>(s, "IsDeleted")) && __ef_filter__p_1 || (Guid?)EF.Property<Guid>(s, "TenantId") == __ef_filter__CurrentTenantId_2)
    .Where(s => __keyCompliled_0.Invoke(s).ToString() == __ToString_2)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
System.InvalidOperationException: The LINQ expression 'DbSet<SubscriptionType>()
    .Where(s => __ef_filter__p_0 || !(EF.Property<bool>(s, "IsDeleted")) && __ef_filter__p_1 || (Guid?)EF.Property<Guid>(s, "TenantId") == __ef_filter__CurrentTenantId_2)

请注意,除非在查询中应用条件 (WhereIf),否则一切正常。该错误特别发生在使用条件逻辑过滤数据的场景中。

.net entity-framework linq-to-sql
1个回答
0
投票

起初,我认为

WhereIf
无法翻译为数据库脚本,但看起来可以。

卷轴答案是:该功能不能用于

IQueryable
对象。它适用于
IEnumerable

请参阅此链接:如何在 LINQ 中使用 whereif

© www.soinside.com 2019 - 2024. All rights reserved.