Andrei
Andrei

Reputation: 44580

Convert Entity Framework Core entity into SQL string

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

Upvotes: 2

Views: 1801

Answers (2)

Andrei
Andrei

Reputation: 44580

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

Upvotes: 1

Ivan Stoev
Ivan Stoev

Reputation: 205579

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();

Upvotes: 2

Related Questions