LinqKit 通过扩展方法应用嵌套过滤不起作用
LinqKit applying nested filtering through extension-method not working
我在将 LinqKit 与 EF Core 结合使用时遇到了一个奇怪的行为。
这是我的查询:
var divisionFilter = new DivisionFilter
{
VisibilityFilter = (DivisionVisibilityFilter)true
};
await DbContext.Events.Get(new EventFilter
{
IsVisibleFilter = (EventIsVisibleFilter)true,
IdIncludeExcludeFilter = (EventIdIncludeExcludeFilter)new IncludeExcludeFilter<Guid> { Includes = new[] { eventId } }
}).Select(e => new
{
Divisions = e.Divisions
.Get(divisionFilter) // throws excepetion
.Where(d2 => divisionFilter.FilterExpression.Expand().Invoke(d2)) // works fine
.Select(division => new
{
division.DivisionId,
division.DivisionName,
division.DivisionGender
})
}).SingleAsync()
目前我使用两个扩展来应用 FilterExpression
类型的过滤器 Expression<Func<TEntity, bool>>
public static IQueryable<TEntity> Get<TEntity, TEntityFilter>(this DbSet<TEntity> dbSet, TEntityFilter filter)
where TEntity : BaseEntity<TEntity>, new()
where TEntityFilter : EntityFilter<TEntity>
{
return dbSet.AsExpandable().Where(entity => filter.FilterExpression.Invoke(entity));
}
public static IEnumerable<TEntity> Get<TEntity, TEntityFilter>(this IEnumerable<TEntity> entities, TEntityFilter filter)
where TEntity : BaseEntity<TEntity>, new()
where TEntityFilter : EntityFilter<TEntity>
{
return entities.Where(e => filter.FilterExpression.Expand().Invoke(e));
}
而第一个将 AsExpandable
应用于顶部-table,第二个用于过滤嵌套的导航属性。
但是,如果在嵌套的 属性 上使用 Get
,则会抛出异常
The LINQ expression 'division' could not be translated
来自 Select
-子句。
如果我直接使用 Where
子句并添加 Expand().Invoke(d2)
它会按预期工作,但在使用扩展时不会。
在我看来,这两个调用是相同的,但显然它们不是,而且我看不出问题所在。
您必须将 Get
方法标记为可扩展:
[Expandable(name(GetEnumerable))]
public static IEnumerable<TEntity> Get<TEntity, TEntityFilter>(this IEnumerable<TEntity> entities, TEntityFilter filter)
where TEntity : BaseEntity<TEntity>, new()
where TEntityFilter : EntityFilter<TEntity>
{
return entities.Where(e => filter.FilterExpression.Expand().Invoke(e));
}
private static Expression<Func<IEnumerable<TEntity>, TEntityFilter, IEnumerable<TEntity>>> GetEnumerablet<TEntity, TEntityFilter>()
{
return (entities, filter) =>
entities.Where(e => filter.FilterExpression.Expand().Invoke(e));
}
我在将 LinqKit 与 EF Core 结合使用时遇到了一个奇怪的行为。
这是我的查询:
var divisionFilter = new DivisionFilter
{
VisibilityFilter = (DivisionVisibilityFilter)true
};
await DbContext.Events.Get(new EventFilter
{
IsVisibleFilter = (EventIsVisibleFilter)true,
IdIncludeExcludeFilter = (EventIdIncludeExcludeFilter)new IncludeExcludeFilter<Guid> { Includes = new[] { eventId } }
}).Select(e => new
{
Divisions = e.Divisions
.Get(divisionFilter) // throws excepetion
.Where(d2 => divisionFilter.FilterExpression.Expand().Invoke(d2)) // works fine
.Select(division => new
{
division.DivisionId,
division.DivisionName,
division.DivisionGender
})
}).SingleAsync()
目前我使用两个扩展来应用 FilterExpression
类型的过滤器 Expression<Func<TEntity, bool>>
public static IQueryable<TEntity> Get<TEntity, TEntityFilter>(this DbSet<TEntity> dbSet, TEntityFilter filter)
where TEntity : BaseEntity<TEntity>, new()
where TEntityFilter : EntityFilter<TEntity>
{
return dbSet.AsExpandable().Where(entity => filter.FilterExpression.Invoke(entity));
}
public static IEnumerable<TEntity> Get<TEntity, TEntityFilter>(this IEnumerable<TEntity> entities, TEntityFilter filter)
where TEntity : BaseEntity<TEntity>, new()
where TEntityFilter : EntityFilter<TEntity>
{
return entities.Where(e => filter.FilterExpression.Expand().Invoke(e));
}
而第一个将 AsExpandable
应用于顶部-table,第二个用于过滤嵌套的导航属性。
但是,如果在嵌套的 属性 上使用 Get
,则会抛出异常
The LINQ expression 'division' could not be translated
来自 Select
-子句。
如果我直接使用 Where
子句并添加 Expand().Invoke(d2)
它会按预期工作,但在使用扩展时不会。
在我看来,这两个调用是相同的,但显然它们不是,而且我看不出问题所在。
您必须将 Get
方法标记为可扩展:
[Expandable(name(GetEnumerable))]
public static IEnumerable<TEntity> Get<TEntity, TEntityFilter>(this IEnumerable<TEntity> entities, TEntityFilter filter)
where TEntity : BaseEntity<TEntity>, new()
where TEntityFilter : EntityFilter<TEntity>
{
return entities.Where(e => filter.FilterExpression.Expand().Invoke(e));
}
private static Expression<Func<IEnumerable<TEntity>, TEntityFilter, IEnumerable<TEntity>>> GetEnumerablet<TEntity, TEntityFilter>()
{
return (entities, filter) =>
entities.Where(e => filter.FilterExpression.Expand().Invoke(e));
}