EF Core Migration
Here are a few changes I came across migrating a medium sized app from 4.7.2 to Core 2.1.
There are some pretty significant differences, especially with model annotations. Fluent API handles most of the configuration now.
Global changes, such as a default string length, take a bit more effort to implement.
Indexes can no longer be created through data annotations and must be created through fluent api
EF6
[Index("IX_ClientApplication", 1, IsUnique = true)]
public int ClientUserId { get; set; }
[Index("IX_ClientApplication", 2, IsUnique = true)]
public int ClientApplicationId { get; set; }
EF7
modelBuilder.Entity<ClientUserClientApplication>()
.HasIndex(x => new { x.ClientUserId, x.ClientApplicationId })
.IsUnique();
HasRequired is now HasOne when setting table props through fluent api
EF7
modelBuilder.Entity<ClientApplication>()
.HasOne(c => c.Client)
.WithMany(c => c.ClientApplications)
.HasForeignKey(c => c.ClientId);
WillCascadeOnDelete(false) replaced with .OnDelete(DeleteBehavior.Restrict)
EF6
modelBuilder.Entity<ClientApplicationRoleClaim>()
.HasRequired(x => x.ClientApplicationRole)
.WithMany(x => x.ClientApplicationRoleClaims)
.WillCascadeOnDelete(false);
EF7
modelBuilder.Entity<ClientApplicationRoleClaim>()
.HasOne(x => x.ClientApplicationRole)
.WithMany(x => x.ClientApplicationRoleClaims)
.OnDelete(DeleteBehavior.Restrict);
HasOptional has no equivalent in EF7 - null foreign key will make the relationaship optional under the hood.
EF6
modelBuilder.Entity<Fund>()
.HasOptional(c => c.Distributor)
.WithMany()
.WillCascadeOnDelete(false);
EF7
modelBuilder.Entity<Fund>()
.HasOne(c => c.Distributor)
.WithMany()
.HasForeignKey(x => x.DistributorId)
.OnDelete(DeleteBehavior.Restrict);
IDbSet is gone in EF7
Removing pluralization takes a bit more work
EF6
modelBuilder.Conventions
.Remove<PluralizingTableNameConvention>();
EF7
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
modelBuilder.Entity(entityType.Name)
.ToTable(entityType.Name.Replace("PAC.ETL.Model.",""));
}
So does setting default string length
EF6
modelBuilder.Properties<string>()
.Configure(p => p.HasMaxLength(50));
EF7
foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(string)))
{
if (property.GetMaxLength() == null)
property.SetMaxLength(50);
}
Setting precision takes a bit more work as well
EF6
modelBuilder.Properties<DateTime>()
.Configure(c => c.HasColumnType("datetime2").HasPrecision(2));
EF7
foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
)
{
if (property.ClrType == typeof(string) &&
property.GetMaxLength() == null)
property.SetMaxLength(50);
if (property.ClrType == typeof(DateTime) )
property.Relational().ColumnType = "datetime2(2)";
if (property.ClrType == typeof(TimeSpan))
property.Relational().ColumnType = "time(0)";
}