从EF6转移到EF Core 2.0

15

我刚开始将我的MVC5项目从EF6x迁移到MVC Core和EF Core,但是在实体配置方面遇到了大问题。你如何将EF6 Fluent配置迁移到EF Core?
如果可能的话,我需要一个带有示例的指南。

这是我的一个映射类和我的尝试

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多个配置类,所以在继续之前我会向您询问。如果我的问题内容不符合网站的条款和条件,请谅解。


4
我知道的唯一转换工具是人类开发者。 - Gert Arnold
1
你的转换看起来没问题。你有什么疑虑吗?你有具体的问题吗? - Ivan Stoev
1
为了进行测试,您可以先配置部分实体,然后稍后再配置其余部分。没有什么比自己尝试更好的替代方法。 - Sefe
1
感谢您抽出时间阅读我的帖子 @IvanStoev。 - hitasp
1
另外,请注意EF Core与EF6具有不同的映射选项。例如,不支持使用隐藏连接类的多对多关系,但已添加了其他选项,如更多建模一对一关联的方式和使用备用键。这可能是自动转换从未被实现的原因之一。 - Gert Arnold
显示剩余5条评论
1个回答

22

我找到了一篇关于迁移到EF Core的好文章,想分享给像我这样的初学者。

代码更新
命名空间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同理。我所做的是将所有includes和orderbys移动到最后。

来源:从EF6迁移到EF Core


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接