LINQKit icon indicating copy to clipboard operation
LINQKit copied to clipboard

LinqKit applying nested filtering through extension-method not working

Open kuebelkasten opened this issue 5 years ago • 12 comments

See stackoverflow fo details.

Seems like the Get is never called (breakpoints never hit). I already tried using Expression.Lambda<> Compile(), Invoke() and Expand() but still, the extension seems not be invoked before the exception is thrown.

On the other hand, using Where works as expected.

kuebelkasten avatar Mar 15 '21 16:03 kuebelkasten

@kuebelkasten, it is your question in SO?

sdanyliv avatar Mar 15 '21 19:03 sdanyliv

@sdanyliv Yes. Was not sure if I need to repeat it completely here again. But would be possible to edit my issue here if needed

kuebelkasten avatar Mar 16 '21 07:03 kuebelkasten

Well, answer added: https://stackoverflow.com/a/66650693/10646316

sdanyliv avatar Mar 16 '21 07:03 sdanyliv

@sdanyliv I've added the Expandable-attribute to the Get extension-method ending up in exception

[Expandable]
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.Invoke(e));
}

No generic method 'Get' on type 'Project.Database.Extensions.DbSetExtensions' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

Could it be possbile that the issue is because there are two methods named Get?

kuebelkasten avatar Mar 16 '21 07:03 kuebelkasten

It is not correct way of using Expandable attribute and is not original SO question.

sdanyliv avatar Mar 16 '21 07:03 sdanyliv

Sorry. I copied the wrong link to the SO-question. Should be stackoverflow I updated the question accordingly. No idea where the wrong link was from...

kuebelkasten avatar Mar 16 '21 08:03 kuebelkasten

Done.

sdanyliv avatar Mar 16 '21 08:03 sdanyliv

@sdanyliv Awesome. Well appreciated. In your copied code there is just one > at the wrong position in GetEnumerable but then it works like a charm. Many thanks 👍

kuebelkasten avatar Mar 16 '21 08:03 kuebelkasten

Anyway, try to remove Expand, probably it may work also.

sdanyliv avatar Mar 16 '21 08:03 sdanyliv

Yupp. Removed Expand() in both methods and it still works as expected

kuebelkasten avatar Mar 16 '21 08:03 kuebelkasten

Maybe @sdanyliv could help me out with this again as it may be related. I have the following query:

await DbContext.Events.Get(new EventFilter
{
	IsVisibleFilter = (EventIsVisibleFilter)true,
	IdIncludeExcludeFilter = (EventIdIncludeExcludeFilter)new IncludeExcludeFilter<Guid> { Includes = new[] { eventId } }
}).Select(e => new
{
	EventTeams = e.EventTeams
		.Get(new EventTeamFilter { IsVisibleFilter = (EventTeamIsVisibleFilter)true })
		.Select(et => new
		{
			et.EventTeamTeam.TeamId,
			et.EventTeamTeam.TeamName,
			Players = et.EventTeamDivision.EventPlayers
				.Get(new EventPlayerFilter
				{
					IsVisibleFilter = (EventPlayerIsVisibleFilter)true,
					TeamFilter = new TblTeamFilter { IdIncludeExcludeFilter = (TeamIdIncludeExcludeFilter)new IncludeExcludeFilter<Guid> { Includes = new[] { et.EventTeamTeamId } } } // here is the exception
				})
				//.Where(tit => tit.EventPlayerTeamId == et.EventTeamTeamId) // this works
				.Select(pit => new
				{
					pit.EventPlayerPlayer.PlayerId,
					pit.EventPlayerPlayer.PlayerFirstName,
					pit.EventPlayerPlayer.PlayerLastName,
				})
		})
}).SingleAsync()

If I run this query I get the exception

System.InvalidOperationException: variable 'et' of type 'Project.Database.Entities.EventTeam' referenced from scope '', but it is not defined

When changing the second Get-call to Where:

.Where(pit => new EventPlayerFilter
{
	IsVisibleFilter = (EventPlayerIsVisibleFilter)true,
	TeamFilter = new TblTeamFilter { IdIncludeExcludeFilter = (TeamIdIncludeExcludeFilter)new IncludeExcludeFilter<Guid> { Includes = new[] { et.EventTeamTeamId } } }
}.FilterExpression.Compile().Invoke(pit))

the exception

.FilterExpression.Compile().Invoke(t4))' 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.

kuebelkasten avatar Mar 17 '21 12:03 kuebelkasten

I need full call stack. Anyway, weird filtering technique.

sdanyliv avatar Mar 17 '21 17:03 sdanyliv