英文:
Can I convert a .ConvertToProvider from Func<object, object> to a more precise type?
问题
My table T_SHIP has a column FULL_TANK, containing "Y" if the ship's fuel tank is full, "N" if it isn't, and Null if the ship doesn't have a tank, such as a sailing ship.
I define an entity property for that column as such:
p_etbTable.Property(t => t.HasFullTank).HasColumnName("FULL_TANK")
.HasColumnType("varchar(1)")
.HasConversion(ConversionsHelper.BooleanToY_N);
with BooleanToY_N a simple ValueConverter object:
public static ValueConverter<bool?, string> BooleanToY_N =
new ValueConverter<bool?, string>(b => b.HasValue ? (b.Value ? "Y" : "N") : null,
s => s == "Y");
In my code, I want to be able to access the values "Y" and "N" directly from BooleanToY_N, as an alternative to constants.
IConventionAnnotation z_annConverterHasFullTank =
((IConventionAnnotatable)new MyDbContext().Model
.GetEntityTypes()
.FirstOrDefault(et => et.ClrType == typeof(TShip))
.GetProperties()
.First(pr => pr.Name == nameof(TShip.HasFullTank)))
.GetAnnotation(nameof(EF_Storage.ValueConversion.ValueConverter));
EF_Storage.ValueConversion.ValueConverter<bool?, string> z_vcoConverterHasFullTank =
(EF_Storage.ValueConversion.ValueConverter<bool?, string>)z_annConverterHasFullTank.Value;
Func<object, object> z_funConversionHasFullTank = z_vcoConverterHasFullTank.ConvertToProvider;
and then use z_funConversionHasFullTank.Invoke() by passing it false or true to get "N" or "Y", respectively, then use .ToString() to convert it to a string.
This works quite well, but to simplify the use of z_funConversionHasFullTank, I'd like to define it as Func<bool?, string>.
When I do, the compiler informs me that it cannot convert Func<object, object> to Func<bool?, string>. Still, since there's a Func<bool?, string> in there I feel I should be able to get it out. Does anyone have an idea how that could be done?
英文:
My table T_SHIP has a column FULL_TANK, containing "Y" if the ship's fuel tank is full, "N" if it isn't, and Null if the ship doesn't have a tank, such as a sailing ship.
I define an entity property for that column as such:
p_etbTable.Property(t => t.HasFullTank).HasColumnName("FULL_TANK")
.HasColumnType("varchar(1)")
.HasConversion(ConversionsHelper.BooleanToY_N);
with BooleanToY_N a simple ValueConverter object:
public static ValueConverter<bool?, string> BooleanToY_N =
new ValueConverter<bool?, string>(b => b.HasValue ? (b.Value ? "Y" : "N") : null,
s => s == "Y");
In my code, I want to be able to access the values "Y" and "N" directly from BooleanToY_N, as an alternative to constants.
IConventionAnnotation z_annConverterHasFullTank =
((IConventionAnnotatable)new MyDbContext().Model
.GetEntityTypes()
.FirstOrDefault(et => et.ClrType == typeof(TShip))
.GetProperties()
.First(pr => pr.Name == nameof(TShip.HasFullTank)))
.GetAnnotation(nameof(EF_Storage.ValueConversion.ValueConverter));
EF_Storage.ValueConversion.ValueConverter<bool?, string> z_vcoConverterHasFullTank =
(EF_Storage.ValueConversion.ValueConverter<bool?, string>)z_annConverterHasFullTank.Value;
Func <object, object> z_funConversionHasFullTank = z_vcoConverterHasFullTank.ConvertToProvider.;
and then use z_funConversionHasFullTank.Invoke() by passing it false or true to get "N" or "Y", respectively, then use .ToString() to convert it to a string.
This works quite well, but to simplify the use of z_funConversionHasFullTank, I'd like to define it as Func<bool?, string>.
When I do, the compiler informs me that it cannot convert Func<object, object> to Func<bool?, string>. Still, since there's a Func<bool?, string> in there I feel I should be able to get it out. Does anyone have an idea how that could be done?
答案1
得分: 1
Your expression is of the wrong type, must be:
ValueConverter<bool?, string?>
Because the string can also be null. Then it has a bug, it won't return null when the provider (string) is null but false instead:
new ValueConverter<bool?, string?>(
b => b.HasValue ? (b.Value ? "Y" : "N") : null,
s => s == null ? null : s == "Y"
);
(Or s => s == null ? null : (bool?)s == "Y" for earlier C# versions).
Finally, you're right in that ConvertToProvider is a Func<object?, object?> and that you can't cast that to Func<bool?, string?>, but luckily there's also a ConvertToProviderExpression which is an Expression<Func<bool?, string?>>:
Func<bool?, string?> toProvider = z_vcoConverterHasFullTank.ConvertToProviderExpression.Compile();
英文:
Your expression is of the wrong type, must be:
ValueConverter<bool?, string?>
Because the string can also be null. Then it has a bug, it won't return null when the provider (string) is null but false instead:
new ValueConverter<bool?, string?>(
b => b.HasValue ? (b.Value ? "Y" : "N") : null,
s => s == null ? null : s == "Y"
);
(Or s => s == null ? null : (bool?)s == "Y" for earlier C# versions).
Finally, you're right in that ConvertToProvider is a Func<object?, object?> and that you can't cast that to Func<bool?, string?>, but luckily there's also a ConvertToProviderExpression which is an Expression<Func<bool?, string?>>:
Func<bool?, string?> toProvider = z_vcoConverterHasFullTank.
ConvertToProviderExpression.Compile();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论