-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NullReferenceException
for a custom ValueConverter
in EF Core 9 RC 1.
#34760
Comments
@maliming you can workaround the problem by slightly modifying the converter: public class MyDateTimeValueConverter : ValueConverter<DateTime, DateTime>
{
public MyDateTimeValueConverter(ConverterMappingHints? mappingHints = null)
: base(
x => new MyDatetimeConverter().Normalize(x),
x => new MyDatetimeConverter().Normalize(x),
mappingHints)
{
}
} and the model configuration part: modelBuilder.Entity<Book>().Property(e => e.CreationDate).HasConversion(new MyDateTimeValueConverter()); Basically, rather than passing |
shaper we generate:
We use generic CLR DateTime to find mapping for the value, and that obviously doesn't have the converter. We can't use converter ctor expression because it contains an unliftable constant, so we "fall back" to the dummy way of doing things.
This essentially is dupe of #33517 this is a breaking change, so we should document this, as the workaround is not intuitive at all @roji |
@maumar are you suggest we document this as a by-design regression? Isn't it a bug that we need to fix (and probably service)? |
it's a bug/limitation of the current liftable constant approach. I'd service this but i'm worried how risky the fix is going to be. |
OK. It in any case seems like a bug (and a regression at that) rather than an intended change... Ideally we'd make sure this scenario works in regular mode even if it doesn't in precompiled/AOT mode (which is experimental anyway, etc.); I think it's OK for now if we'd throw an exception eagerly if a value converter with a captured variable is used with precompilation, as long as things work in normal mode... Let me know what you think. BTW note that the workaround instantiates a converter instance each and every time a value is converted, which is a bit problematic perf-wise. |
yeah, I thought about it over night and I do agree. I don't think we have a way to fix it right now in a way that would work for AOT (need #33517 for that), but we could revert to pre-AOT pattern in these specific scenarios. |
Yeah, that sounds right. |
… EF Core 9 RC 1. For AOT/precompiled queries we now do special processing (lifting) of all non-literal constants. We essentially provide a way to resolve the constant from well established entry points, e.g. model. Problem happens for cases where we are projecting a property with a custom converter but do it in such a way that we lose the IProperty information (e.g. by projecting individual property, rather than as part of an entity) Without IProperty information we can't reliably extract the proper type mapping for that property and as a result we don't know what custom converter to use. What we used to do is "guess" the type mapping based on CLR type of the property. This is pretty much always wrong, and it also broke non-precompiled scenarios. Fix is to just use ConvertFromProviderExpression expression irrespective of whether it contains closures or not. We only do that if we don't have the IProperty information. This also requires disabling non-literal constant validation we do in the post processing, as now some queries may contain "unliftable" constants. We should re-enable the validation once the issue is properly addressed (#33517) Fixes #34760
… EF Core 9 RC 1. For AOT/precompiled queries we now do special processing (lifting) of all non-literal constants. We essentially provide a way to resolve the constant from well established entry points, e.g. model. Problem happens for cases where we are projecting a property with a custom converter but do it in such a way that we lose the IProperty information (e.g. by projecting individual property, rather than as part of an entity) Without IProperty information we can't reliably extract the proper type mapping for that property and as a result we don't know what custom converter to use. What we used to do is "guess" the type mapping based on CLR type of the property. This is pretty much always wrong, and it also broke non-precompiled scenarios. Fix is to just use ConvertFromProviderExpression expression irrespective of whether it contains closures or not. We only do that if we don't have the IProperty information. This also requires disabling non-literal constant validation we do in the post processing, as now some queries may contain "unliftable" constants. We should re-enable the validation once the issue is properly addressed (#33517) Fixes #34760
… EF Core 9 RC 1. For AOT/precompiled queries we now do special processing (lifting) of all non-literal constants. We essentially provide a way to resolve the constant from well established entry points, e.g. model. Problem happens for cases where we are projecting a property with a custom converter but do it in such a way that we lose the IProperty information (e.g. by projecting individual property, rather than as part of an entity) Without IProperty information we can't reliably extract the proper type mapping for that property and as a result we don't know what custom converter to use. What we used to do is "guess" the type mapping based on CLR type of the property. This is pretty much always wrong, and it also broke non-precompiled scenarios. Fix is to just use ConvertFromProviderExpression expression irrespective of whether it contains closures or not. We only do that if we don't have the IProperty information. This also requires disabling non-literal constant validation we do in the post processing, as now some queries may contain "unliftable" constants. We should re-enable the validation once the issue is properly addressed (#33517) Fixes #34760
… EF Core 9 RC 1. For AOT/precompiled queries we now do special processing (lifting) of all non-literal constants. We essentially provide a way to resolve the constant from well established entry points, e.g. model. Problem happens for cases where we are projecting a property with a custom converter but do it in such a way that we lose the IProperty information (e.g. by projecting individual property, rather than as part of an entity) Without IProperty information we can't reliably extract the proper type mapping for that property and as a result we don't know what custom converter to use. What we used to do is "guess" the type mapping based on CLR type of the property. This is pretty much always wrong, and it also broke non-precompiled scenarios. Fix is to just use ConvertFromProviderExpression expression irrespective of whether it contains closures or not. We only do that if we don't have the IProperty information. This also requires disabling non-literal constant validation we do in the post processing, as now some queries may contain "unliftable" constants. We should re-enable the validation once the issue is properly addressed (#33517) Fixes #34760
fixed in 8561f4e |
Also reported via #34934 |
The
csproj
and code to reproduce:It works if I create the
MyDatetimeConverter()
object in the expression parameter.And the all code works in EF Core 8.0.
The text was updated successfully, but these errors were encountered: