Convert Entity Framework Core entity into SQL string

.net-core c# entity-framework entity-framework-core

Question

I'm trying to generate a SQL MERGE statement from Entity Framework Core entity. To do so I need to convert all entity properties into SQL strings e.g:

bool   => 1 or 0
string => 'string'
int    => 123

It looks like EF Core uses class ValueConverterSelector as a factory for all different internal as well as custom value converters. I need to get it from context. How can I do it?


UPDATE: Thanks to Ivan Stoev, he proposed the following way to get converterSelector:

var converterSelector = context.GetInfrastructure().GetService<IValueConverterSelector>()
var converters = converterSelector.Select(entry.Metadata.ClrType, prop.Metadata.ClrType);
// Converters collection is empty ;(

I'm facing a new issue with it. By inspecting private fields I see that this selector has no converters registered. Hence I still can't get the right converter for each property for the entities. I need a converter selector with exact custom and built-in converters that EF is using. Any ideas?

enter image description here

1
2
6/22/2019 5:20:22 PM

Accepted Answer

To get SQL value for property using Entity Framework you would need to:

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);
1
6/21/2019 4:53:22 PM

Popular Answer

You can obtain any of the EF Core context services by adding

using Microsoft.EntityFrameworkCore.Infrastructure;

which gives you access to the extensions methods defined in the AccessorExtensions class, and in particular GetService method.

So for the concrete question you would use something like this:

using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

var valueConverterSelector = dbContext.GetService<IValueConverterSelector>();

Not every property has associated value converter. Currently (EF Core 2.2) you can obtain the value converter for IProperty similar to how EF Core does it using a code snippet like this:

using Microsoft.EntityFrameworkCore.Metadata.Internal;

IProperty property;
var valueConverter = property.FindMapping()?.Converter ?? property.GetValueConverter();


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow