2

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.
Matt
  • 1,648
  • 12
  • 22
  • Can't you just use a variation of [Loop/reflect through all properties in all EF Models to set Column Type](https://stackoverflow.com/questions/41468722/loop-reflect-through-all-properties-in-all-ef-models-to-set-column-type/41469383#41469383)? – Ivan Stoev Aug 25 '17 at 13:57
  • @IvanStoev tried this - has no effect on the migration that is rendered. – Matt Aug 25 '17 at 13:59
  • In my tests it is considered by the migration generator. And there is no other way currently (even in 2.0) AFAIK. But would be interesting if you/someone find something. Good luck. – Ivan Stoev Aug 25 '17 at 14:03

1 Answers1

1

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()");
}
Matt
  • 1,648
  • 12
  • 22