EF Core model building conventions

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

Question

In EF6 it was possible to define conventions based on property types during model building, like so...

public interface IEntity
{
    Guid Id { get; }
}

public class MyEntity : IEntity
{
    public Guid Id { get; set; }
}

public class MyDbContext : DbContext
{
    public override void OnModelCreating(DbModelBuilder builder)
    {
        builder
            .Properties<Guid>()
            .Where(x => x.Name == nameof(IEntity.Id)
            .Configure(a=>a.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity));
    }
}

This approach could also be used to set default string length/null-ness, and so forth.

I have looked through the EF Core Model and associated types and can find no way of applying an equivalent convention in a way that is either enacted by the migration builder, or that does not cause migration builder to reject the model altogether. This is entirely frustrating and seems regressive.

Update

Adding the following to the OnModelCreating event...

foreach (var pb in builder.Model
    .GetEntityTypes()
    .Where(x=>typeof(IEntity).IsAssignableFrom(x.ClrType))
    .SelectMany(t => t.GetProperties())
    .Where(p => p.ClrType == typeof(Guid) && p.Name == nameof(IEntity.Id))
    .Select(p => builder.Entity(p.DeclaringEntityType.ClrType).Property(p.Name)))
{
    pb.UseSqlServerIdentityColumn();
}

...produces the following message on Add-Migration

Identity value generation cannot be used for the property 'Id' on entity type 'Tenant' because the property type is 'Guid'. Identity value generation can only be used with signed integer properties.
1
2
8/25/2017 2:12:31 PM

Accepted Answer

This does the job, but it's pretty inelegant.

foreach (PropertyBuilder pb in builder.Model
    .GetEntityTypes()
    .Where(x=>typeof(IEntity).IsAssignableFrom(x.ClrType))
    .SelectMany(t => t.GetProperties())
    .Where(p => p.ClrType == typeof(Guid) && p.Name == nameof(IEntity.Id))
    .Select(p => builder.Entity(p.DeclaringEntityType.ClrType).Property(p.Name)))
{
    pb.ValueGeneratedOnAdd().HasDefaultValueSql("newsequentialid()");
}
1
8/25/2017 2:26:24 PM


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