Default value for property according to type Ef core

Asked

Viewed 321 times

0

I have a code in which I define some properties according to the type of variable in EF6

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties().Where(p => p.Name == p.ReflectedType.Name + "Id").Configure(p => p.IsKey());

    modelBuilder.Properties<string>().Configure(p => p.HasColumnType("varchar"));

    modelBuilder.Properties<string>().Configure(p => p.HasMaxLength(50));
}

How to configure these properties according to type in EF Core?

  • What’s the problem with that ? try changing Dbmodelbuilder to Modelbuilder

1 answer

2


the EF Core has no such method, but you can extend the ModelBuilder for it to gain this functionality.

A while ago, I needed to configure the properties of a certain interface. But as you might imagine, the builder.Entity<T> does not accept a Interface as a first argument.

So I implemented the following method in a static class.:

public static void Entities<T>(this ModelBuilder builder, DbContext instance, string methodName)
{
    var method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
    var typesStatus = builder.Model.GetEntityTypes().Where(type => typeof(T).IsAssignableFrom(type.ClrType));
    foreach (var type in typesStatus)
    {
        var builderType = typeof(EntityTypeBuilder<>).MakeGenericType(type.ClrType);
        var buildMethod = method.MakeGenericMethod(type.ClrType);
        var buildAction = typeof(Action<>).MakeGenericType(builderType);
        var buildDelegate = Delegate.CreateDelegate(buildAction, instance, buildMethod);
        var buildEntity = typeof(ModelBuilder).GetMethods()
            .Single(m => m.Name == "Entity" && m.GetGenericArguments().Any() && m.GetParameters().Any())
            .MakeGenericMethod(type.ClrType);

        buildEntity.Invoke(builder, new[] { buildDelegate });
    }
}

The call to this method became something like.:

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entities<IInterfaceA>(this, nameof(this.ModelInterfaceA));
    builder.Entities<IInterfaceB>(this, nameof(this.ModelInterfaceB));
}

private void ModelInterfaceA<T>(EntityTypeBuilder<T> entity) where T : class, IInterfaceA
{
    entity.HasQueryFilter(x => x.Ativo);
    entity.Property(x => x.Data).HasColumnType("datetime2(2)");
}

private void ModelInterfaceB<T>(EntityTypeBuilder<T> entity) where T : class, IInterfaceB
{
    entity.Property(x => x.Property).HasColumnType("...");
}

Modifying the extension to work with properties.

For your specific case, I will make an adaptation of the above-mentioned method.:

public static void Properties<T>(this ModelBuilder builder, Action<PropertyBuilder<T>> callback)
{
    var types = builder.Model.GetEntityTypes();
    foreach (var type in types)
    {
        var entityBuilderType = typeof(EntityTypeBuilder<>).MakeGenericType(type.ClrType);

        var buildEntity = typeof(ModelBuilder).GetMethods()
            .Single(m => m.Name == "Entity" && m.GetGenericArguments().Any() && !m.GetParameters().Any())
            .MakeGenericMethod(type.ClrType);

        var buildProperty = entityBuilderType.GetMethods()
            .Single(m => m.Name == "Property" && m.GetGenericArguments().Any() && m.GetParameters().Any(p => p.ParameterType == typeof(string)))
            .MakeGenericMethod(type.ClrType);

        var entityTypeBuilder = buildEntity.Invoke(builder, null);
        var properties = type.GetProperties().Where(x => x.GetType().Equals(typeof(T)));
        foreach (var property in properties)
        {
            var propertyBuilder = buildProperty.Invoke(entityTypeBuilder, new[] { property.Name }) as PropertyBuilder<T>;
            callback(propertyBuilder);
        }
    }
}

its use is even simpler.:

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Properties<string>(config => {
        config.HasColumnType("varchar(50)");
    })
}

The above method has not been tested, in any case you can use the original algorithm to improve or correct the suggested correction.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.