将实体框架核心实体转换为SQL字符串

时间:2019-06-20 23:14:33

标签: c# entity-framework .net-core entity-framework-core

我正在尝试从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正在使用的确切的自定义和内置转换器。有什么想法吗?

enter image description here

2 个答案:

答案 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);