EntityFramework.Filters icon indicating copy to clipboard operation
EntityFramework.Filters copied to clipboard

Nullable types and EntityFramework.Filters

Open easyest opened this issue 10 years ago • 4 comments

EntityFramework 6.

The query:

var item = context.Items.FirstOrDefault(x => x.NullableProperty == filter.NullablePropertyValue);

Without EntityFramework.Filters it translates to:

...
WHERE (([Extent1].[NullableProperty] = @p__linq__0) OR (([Extent1].[NullableProperty] IS NULL) AND (@p__linq__0 IS NULL)))

After adding filter interceptor (both in DbConfiguration class or in OnModelCreating) the query is translated to:

...
WHERE ([Extent1].[NullableProperty] = @p__linq__0) 

DBContext.Configuration.UseDatabaseNullSemantics = false; does not fix anything.

easyest avatar Mar 22 '15 16:03 easyest

If your filter.NullablePropertyValue is not null, then

WHERE ([Extent1].[NullableProperty] = @p__linq__0) 

its right. But If your filter.NullablePropertyValue so the query should be just

WHERE (([Extent1].[NullableProperty] IS NULL) AND (@p__linq__0 IS NULL))

AlbertoMonteiro avatar Mar 23 '15 09:03 AlbertoMonteiro

EF 6 has new default behavior - it translates queries for nullable types using this syntax:

WHERE (([Extent1].[NullableProperty] = @p__linq__0) OR (([Extent1].[NullableProperty] IS NULL) AND (@p__linq__0 IS NULL)))

After adding EntityFramework.Filters interceptor to the context this behavior is changed and queries are translated using old syntax i.e. EntityFramework.Filters messes up EntityFramework's behavior and produces unpredicted results. The behavior of EF is controlled by configuration key DBContext.Configuration.UseDatabaseNullSemantics, but when EntityFramework.Filters interceptor is added this configuration does not change anything.

easyest avatar Mar 23 '15 10:03 easyest

I had the same issue in my own extended filterung framework. It's a pretty simple change of the new EF versions > 6.0. They introduced a new property context.Configuration.UseDatabaseNullSemantics. The same property was introduced in the class DbQueryCommandTree, which must be created when filtering the base tree. To solve the issue you only have to change FilterInterceptor.cs:

.... interceptionContext.Result = new DbQueryCommandTree ( queryCommand.MetadataWorkspace, queryCommand.DataSpace, newQuery, validate: false, useDatabaseNullSemantics: interceptionContext.Result.UseDatabaseNullSemantics //otherwise we loose the setting ); ...

That's it :-)

sadisoft avatar Aug 12 '15 15:08 sadisoft

I have fix localy by remplacing in FilterInterceptor.cs:

interceptionContext.Result = new DbQueryCommandTree( queryCommand.MetadataWorkspace, queryCommand.DataSpace, newQuery);

by

interceptionContext.Result = new DbQueryCommandTree( queryCommand.MetadataWorkspace, queryCommand.DataSpace, newQuery,true, context.Configuration.UseDatabaseNullSemantics);

If I have time, I fork and PR after work.

Crazyht avatar Aug 26 '15 14:08 Crazyht