我正在尝试从Entity Framework Core实体生成SQL MERGE语句。为此,我需要将所有实体属性都转换为SQL字符串,例如:
bool => 1 or 0
string => 'string'
int => 123
似乎EF Core使用类ValueConverterSelector
作为所有不同internal以及自定义值转换器的工厂。我需要从上下文中获取它。我该怎么办?
更新:感谢Ivan Stoev,他提出了以下方法来获取converterSelector:
var converterSelector = context.GetInfrastructure().GetService<IValueConverterSelector>()
var converters = converterSelector.Select(entry.Metadata.ClrType, prop.Metadata.ClrType);
// Converters collection is empty ;(
我正面临一个新问题。通过检查私有字段,我看到此选择器未注册任何转换器。因此,我仍然无法为实体的每个属性获得正确的转换器。我需要一个转换器选择器,其中包含EF正在使用的确切的自定义和内置转换器。有什么想法吗?
答案 0 :(得分:2)
您可以通过添加获得任何EF Core上下文服务
using Microsoft.EntityFrameworkCore.Infrastructure;
,它使您可以访问AccessorExtensions类中定义的扩展方法,尤其是GetService方法。
因此,对于具体的问题,您将使用以下内容:
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
var valueConverterSelector = dbContext.GetService<IValueConverterSelector>();
并非每个属性都具有关联的值转换器。当前(EF Core 2.2),您可以获得IProperty的值转换器,类似于EF Core使用如下代码段实现它的方式:
using Microsoft.EntityFrameworkCore.Metadata.Internal;
IProperty property;
var valueConverter = property.FindMapping()?.Converter ?? property.GetValueConverter();
答案 1 :(得分:0)
要使用实体框架获取属性的SQL值,您需要:
var entry = context.Entry(model);
var prop = entry.Properties.First(); // Let's say for the 1st one
var sqlValue = prop.Metadata
.FindRelationalMapping()
.GenerateProviderValueSqlLiteral(prop.CurrentValue);