msawczyn / EFDesigner2022

Entity Framework visual design surface and code-first code generation for EF6, Core and beyond
MIT License
118 stars 21 forks source link

Support value conversions in EFCore5+ #35

Open msawczyn opened 3 years ago

msawczyn commented 3 years ago

https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#modelbuilder-api-for-value-comparers

veeman commented 3 years ago

Currently i implemented this ValueConversion interface with the support of custom attributes and reflection. Maybe the following code can be adopted in the next release.

FieldConverterAttribute constructor prototype (maybe there is already an apropate deifnition in EF for this):

public FieldConvertAttribute(Type targetType)

Custom OnModelCreatedImpl implementation:

partial void OnModelCreatedImpl(ModelBuilder modelBuilder)
{
    // retrieve needed interfaces
    var valueConverter = this.GetService<IValueConverterSelector>();

    // process attributes
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        foreach (var property in entityType.GetProperties())
        {
            // check for field converters
            var attributes = property?.PropertyInfo?.GetCustomAttributes(typeof(FieldConvertAttribute), false);
            if (attributes?.FirstOrDefault() is FieldConvertAttribute convertAttribute)
            {
                var converterInfos = valueConverter.Select(property.ClrType, convertAttribute.TargetType);

                // select first converter if there is any
                if (converterInfos.DefaultIfEmpty().FirstOrDefault() is ValueConverterInfo converterInfo)
                {
                    // create and apply converter
                    var converter = converterInfo.Create();
                    property.SetValueConverter(converter);
                }
                else 
                {
                    // maybe look for another converter sources or throw an exception
                }
            }
        }
    }
}

This looks up the built in property converters defined in EFCore5 - ValueConverterSelector.cs

Usage in EFDesigner CustomAttribute field:

FieldConvert(typeof(string))
msawczyn commented 3 years ago

This is good stuff. Thanks!