从 EF6 迁移到 EF Core 2.0
Moving from EF6 to EF Core 2.0
我刚开始将使用 EF6x 的 MVC5 项目移动到 MVC Core 和 EF Core,但我的实体配置存在很大问题。如何将 EF6 Fluent 配置迁移到 EF 核心?
如果可能的话,我需要一个带样品的指南。
这是我的映射之一 类 和我的尝试
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);
}
}
简单的旧配置
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);
}
}
我的尝试
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);
}
}
我使用 Google 搜索和 Microsoft 文档完成了此操作。但我不确定我的工作。因为我有 +100 配置 类,我会在继续之前问你。如果我的问题内容不符合网站的条款和条件,我深表歉意。
我找到了一篇关于迁移到 EF 核心的好文章。我想分享这个问题,并为像我这样的初学者保留这个问题。
代码更新
命名空间 System.Data.Entity
替换为 Microsoft.EntityFrameworkCore
HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
替换为 ValueGeneratedNever();
DbContext
的基本构造函数没有用于连接字符串的单个字符串参数。我们现在必须注入 DbContextOptions
OnModelCreating(DbModelBuilder modelBuilder)
变为 OnModelCreating(ModelBuilder modelBuilder)
。简单的改变,但还是一样
modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
不再可用,这意味着 EntityTypeConfiguration
也不可用,因此我不得不将所有实体配置移至 OnModelCreating
((IObjectContextAdapter)context).ObjectContext.ObjectMaterialized
不再可用。我用它来扩展 DbContext
以将输出中的所有日期转换为 Utc。我还没有找到替代品。
ComplexType
不再可用。我不得不稍微更改模型结构以适应这一点。
MigrateDatabaseToLatestVersion
不再可用,因此我不得不将以下内容添加到我的 startup.cs
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
serviceScope.ServiceProvider.GetService<SbDbContext>().Database.Migrate();
}
WillCascadeOnDelete(false)
变为 OnDelete(DeleteBehavior.Restrict)
HasOptional
根据 post
不再相关
IDbSet
变为 DbSet
DbSet<T>.Add()
不再是 returns T
而是 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<>)
现在 returns IIncludableQueryable<T,Y>
而不是 IQueryable<T>
,同样适用于 OrderBy
。我所做的是将所有 includes 和 orderbys 移到最后。
我刚开始将使用 EF6x 的 MVC5 项目移动到 MVC Core 和 EF Core,但我的实体配置存在很大问题。如何将 EF6 Fluent 配置迁移到 EF 核心?
如果可能的话,我需要一个带样品的指南。
这是我的映射之一 类 和我的尝试
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);
}
}
简单的旧配置
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);
}
}
我的尝试
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);
}
}
我使用 Google 搜索和 Microsoft 文档完成了此操作。但我不确定我的工作。因为我有 +100 配置 类,我会在继续之前问你。如果我的问题内容不符合网站的条款和条件,我深表歉意。
我找到了一篇关于迁移到 EF 核心的好文章。我想分享这个问题,并为像我这样的初学者保留这个问题。
代码更新
命名空间 System.Data.Entity
替换为 Microsoft.EntityFrameworkCore
HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
替换为 ValueGeneratedNever();
DbContext
的基本构造函数没有用于连接字符串的单个字符串参数。我们现在必须注入 DbContextOptions
OnModelCreating(DbModelBuilder modelBuilder)
变为 OnModelCreating(ModelBuilder modelBuilder)
。简单的改变,但还是一样
modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
不再可用,这意味着 EntityTypeConfiguration
也不可用,因此我不得不将所有实体配置移至 OnModelCreating
((IObjectContextAdapter)context).ObjectContext.ObjectMaterialized
不再可用。我用它来扩展 DbContext
以将输出中的所有日期转换为 Utc。我还没有找到替代品。
ComplexType
不再可用。我不得不稍微更改模型结构以适应这一点。
MigrateDatabaseToLatestVersion
不再可用,因此我不得不将以下内容添加到我的 startup.cs
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
serviceScope.ServiceProvider.GetService<SbDbContext>().Database.Migrate();
}
WillCascadeOnDelete(false)
变为 OnDelete(DeleteBehavior.Restrict)
HasOptional
根据 post
不再相关
IDbSet
变为 DbSet
DbSet<T>.Add()
不再是 returns T
而是 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<>)
现在 returns IIncludableQueryable<T,Y>
而不是 IQueryable<T>
,同样适用于 OrderBy
。我所做的是将所有 includes 和 orderbys 移到最后。