在使用涉及动态条件的方法时,实体框架将 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),否则一切正常。该错误特别发生在使用条件逻辑过滤数据的场景中。
起初,我认为
WhereIf
无法翻译为数据库脚本,但看起来可以。
卷轴答案是:该功能不能用于
IQueryable
对象。它适用于 IEnumerable
。
请参阅此链接:如何在 LINQ 中使用 whereif