问题
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:
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()");
}
来源:https://stackoverflow.com/questions/45882787/ef-core-model-building-conventions