从 EF6 迁移到 EF Core 2.0
Posted
技术标签:
【中文标题】从 EF6 迁移到 EF Core 2.0【英文标题】:Moving from EF6 to EF Core 2.0 【发布时间】:2018-08-15 06:53:10 【问题描述】:我刚开始将使用 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 个配置课程,所以在继续之前我会问你。如果我的问题内容与网站的条款和条件不符,我深表歉意。
【问题讨论】:
我所知道的唯一转换工具是人类开发人员。 您的转换看起来没问题。关你什么事?您有具体问题吗? 对于测试运行,您只能配置部分实体,其余部分稍后配置。自己尝试是无可替代的。 感谢您花时间阅读我的帖子@IvanStoev 另外,请注意 EF 内核的映射选项与 EF6 不同。例如,不支持带有隐藏连接类的多对多,但添加了其他选项,例如更多方式来模拟一对一关联和使用备用键。这可能是从未实施自动转换的原因之一。 【参考方案1】:我找到了一篇关于迁移到 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
根据帖子不再相关IDbSet
变为 DbSet
DbSet<T>.Add()
不再返回 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<>)
现在返回IIncludableQueryable<T,Y>
而不是IQueryable<T>
,同样适用于OrderBy
。我所做的就是将所有的 include 和 orderby 移到最后。
来源:Moving from EF6 to EF Core
【讨论】:
以上是关于从 EF6 迁移到 EF Core 2.0的主要内容,如果未能解决你的问题,请参考以下文章
将现有 Microsoft.AspNet.Identity DB (EF 6) 迁移到 Microsoft.AspNetCore.Identity (EF Core)
执行迁移 EF core 2.0 时出错,将身份 ID 从字符串更改为 int
EF5+SQLserver2012迁移到EF6+mysql5.5.47