EF和现有数据库和表,以及一堆新表

时间:2019-01-09 08:05:09

标签: c# entity-framework

EF和现有数据库和表,以及一堆新表。

上下文:

旧数据库具有新应用程序将使用的表用户。 我使用实体DataModel向导将其映射到this

我现在所拥有的:

一堆新实体及其配置:

public class Bundle
{
    public Bundle() { Produits = new HashSet<Produit>(); }
    public int BundleID { get; set; }
    public string Designation { get; set; }
    public ICollection<Produit> Produits { get; set; }
}

public class BundleConfiguration : EntityTypeConfiguration<Bundle>
{
    public BundleConfiguration()
    {
        ToTable("PL_Bundle");
        HasKey(e => e.BundleID);
        Property(e => e.Designation).HasMaxLength(200);
    }
}

一个DbContext,扩展名是使用反射来映射所有可用配置。

public partial class FooBarDbContext : DbContext
{
    public FooBarDbContext() : base("name=Model1")
       => Database.SetInitializer<FooBarDbContext>(null);

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.ApplyAllConfigurations();
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<User> User { get; set; }
    public DbSet<Bundle> Bundles { get; set; }
    // [...]
}

public static class ModelBuilderExtensions
{
    public static void ApplyAllConfigurations(this DbModelBuilder modelBuilder)
    {
       IEnumerable<Type> typesToRegister
            = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(t => t.GetTypes())
                .Where(t => t.IsClass)
                .Where(type => !string.IsNullOrEmpty(type.Namespace) &&
                        type.GetTypeInfo().BaseType != null &&
                        type.GetTypeInfo().BaseType.GetTypeInfo().IsGenericType &&
                        type.GetTypeInfo().BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>))
                .ToArray();

        foreach (var type in typesToRegister)
        {
            dynamic configurationInstance = Activator.CreateInstance(type);
            modelBuilder.Configurations.Add(configurationInstance);
        }
    }
}

在调用应用程序中,我试图测试数据库和表以检查一切正常。

static void Main(string[] args)
{
    var db = new FooBarCore.DbContext.FooBarDbContext();

    var all = db.User.ToList();        // Work
    var bundles1 = db.Bundles.ToList();     

上一行给我一个错误:

  

无效的目标对象'dbo.PL_Bundle'。 =>无效的对象名称'dbo.PL_Bundle'

我尝试过的事情:

  1. 查找ModelBuilderExtensions是否存在问题。但是使用经典的modelBuilder.Configurations.Add(new BundleConfiguration());。 或直接在OnModelCreating中使用fluent API抛出相同的错误。

  2. 检查数据库=>表不在此处。

  3. 搜索EF not create table,但是CreateDatabaseIfNotExistDropCreateDatabaseWhenModelChangesDropCreateDatabaseAlways令人恐惧,它们都具有该Drop Database的名称。

2 个答案:

答案 0 :(得分:1)

因此,如评论所述:

  

无效的目标对象'dbo.PL_Bundle'。 =>无效的对象名称   'dbo.PL_Bundle'

这意味着EF认为应该有一个表PL_Bundle,但没有。它不存在,因为您在模型中添加了新类。

为了使EF对数据库进行适当的更改,您应该使用名为Migrations

的机制

您必须启用迁移,生成迁移并将其应用到数据库。

优良作法是将迁移也存储为SQL脚本(通过使用UpdateDatabase -script),并让系统管理员手动应用它们,以防止在例如删除列或表时造成任何秘密数据丢失。

您随脚本一起提供了新版本的软件,在应用迁移之前,它应该崩溃,并在日志中说明需要哪一个。

答案 1 :(得分:0)

将您的DbContext类更新为此:

public partial class FooBarDbContext : DbContext
{
    public FooBarDbContext() : base("name=Model1")
       => Database.SetInitializer<FooBarDbContext>(null);

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       //Configurations for Bundle class
       modelBuilder.Entity<Bundle>()
                .ToTable("PL_Bundle")
        .HasKey(e => e.BundleID);
        .Property(e => e.Designation).HasMaxLength(200);

        modelBuilder.ApplyAllConfigurations();
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<User> User { get; set; }
    public DbSet<Bundle> Bundles { get; set; }
    // [...]
}