I just started moving my MVC5 project with EF6x to MVC Core and EF Core but have a big problem with my entities configuration's. How you can migrate a EF6 Fluent configure to EF core?
I need a guide with sample if possible.
Here is one of my mapping classes and my try
EntityMappingConfiguratuin
public interface IEntityMappingConfiguration
{
void Map(ModelBuilder b);
}
public interface IEntityMappingConfiguration<T> : EntityMappingConfiguration where T : class
{
void Map(EntityTypeBuilder<T> builder);
}
public abstract class EntityMappingConfiguration<T> : EntityMappingConfiguration<T> where T : class
{
public abstract void Map(EntityTypeBuilder<T> b);
public void Map(ModelBuilder b)
{
Map(b.Entity<T>());
}
}
public static class ModelBuilderExtenions
{
private static IEnumerable<Type> GetMappingTypes(this Assembly assembly, Type mappingInterface)
{
return assembly.GetTypes().Where(x => !x.IsAbstract && x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType && y.GetGenericTypeDefinition() == mappingInterface));
}
public static void AddEntityConfigurationsFromAssembly(this ModelBuilder modelBuilder, Assembly assembly)
{
var mappingTypes = assembly.GetMappingTypes(typeof(IEntityMappingConfiguration<>));
foreach (var config in mappingTypes.Select(Activator.CreateInstance).Cast<IEntityMappingConfiguration>())
{
config.Map(modelBuilder);
}
}
}
DbContext
public class CommerceServiceDbContext : AbpDbContext
{
public CommerceServiceDbContext(DbContextOptions<CommerceServiceDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.AddEntityConfigurationsFromAssembly(GetType().Assembly);
}
}
Simple old configuration
public partial class AffiliateMap : EntityMappingConfiguration<Affiliate>
{
public override void Map(EntityTypeBuilder<Affiliate> b)
{
b.ToTable("Affiliate");
b.HasKey(a => a.Id);
b.HasRequired(a => a.Address).WithMany().HasForeignKey(x => x.AddressId).WillCascadeOnDelete(false);
}
}
My Try
public partial class AffiliateMap : EntityMappingConfiguration<Affiliate>
{
public override void Map(EntityTypeBuilder<Affiliate> b)
{
b.ToTable("Affiliate");
b.HasKey(a => a.Id);
b.HasOne(a => a.Address)
.WithMany().HasForeignKey(x => x.AddressId).IsRequired().OnDelete(DeleteBehavior.Restrict);
}
}
I've done this using Google Search and Microsoft Documentation. But I'm not sure of my work. Since I have +100 configure classes, I'll ask you before continuing. I apologize if the contents of my question are not compatible with the terms and conditions of the site.
I found a good article about moving to EF core. I want share that and keeping this question for starters like me.
Code Updates
Namespace System.Data.Entity
replaced by Microsoft.EntityFrameworkCore
HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
replaced by ValueGeneratedNever();
The base constructor of DbContext
doesn't have a single string parameter for the connection string. We now have to inject the DbContextOptions
OnModelCreating(DbModelBuilder modelBuilder)
becomes OnModelCreating(ModelBuilder modelBuilder)
. Simple change, but change all the same
modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
is no longer available which means that EntityTypeConfiguration
is also not available, so I had to move all my entity configuration to OnModelCreating
((IObjectContextAdapter)context).ObjectContext.ObjectMaterialized
is no longer available. I was using that to extend the DbContext
to convert all dates in an out to Utc. I haven't found a replacement for that yet.
ComplexType
is no longer available. I had to change the model structure a bit to accomodate this.
MigrateDatabaseToLatestVersion
is no longer available so I had to add the below to my startup.cs
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
serviceScope.ServiceProvider.GetService<SbDbContext>().Database.Migrate();
}
WillCascadeOnDelete(false)
becomes OnDelete(DeleteBehavior.Restrict)
HasOptional
is no longer relevant as per post
IDbSet
becomes DbSet
DbSet<T>.Add()
no longer returns T
but EntityEntry<T>
var entry = context.LearningAreaCategories.Add(new LearningAreaCategory());
//that's if you need to use the entity afterwards
var entity = entry.Entity;
IQueryable<T>.Include(Func<>)
now returns IIncludableQueryable<T,Y>
instead of IQueryable<T>
, same applies for OrderBy
. What I did was moving all the includes and orderbys to the end.
Source: Moving from EF6 to EF Core