Reputation: 44580
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?
Upvotes: 2
Views: 1801
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
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