EF 代码首先告诉我对已经在 db 中的 db 对象进行迁移

Posted

技术标签:

【中文标题】EF 代码首先告诉我对已经在 db 中的 db 对象进行迁移【英文标题】:EF code first telling me to do the migration for db object which is already is in db 【发布时间】:2016-09-13 08:54:36 【问题描述】:

我首先使用 EF 代码。所以最初我在数据库中没有表。所以我写了一些类,当查询这些类时,我看到 EF 代码首先在 db 中创建这些表,但是当我在 db 中创建 sql server 视图,然后用我在 c# 和 EF 项目中的代码映射该视图时,当我尝试查询时查看然后我收到如下错误消息。

附加信息:支持“TestDBContext”上下文的模型自数据库创建以来已更改。考虑使用 Code First 迁移来更新数据库

我知道 EF 告诉我进行迁移,但如果我迁移,那么当视图在 db 中已经存在时,EF 将再次在 db 中创建该视图。

所以告诉我如何通知 EF 我的视图已经在 db 中,因此不需要迁移。 请指导我。谢谢

编辑 1

我的数据库第一次没有表。所以我写了一些像下面这样的类。

public class CustomerBase
    
        public int CustomerID  get; set; 
        public string FirstName  get; set; 
        public string LastName  get; set; 

        public string Address1  get; set; 
        public string Address2  get; set; 

        public string Phone  get; set; 
        public string Fax  get; set; 

    

    public class Customer : CustomerBase
    
        public virtual List<Addresses> Addresses  get; set; 
    

    public class Addresses
    
        [Key]
        public int AddressID  get; set; 
        public string Address1  get; set; 
        public string Address2  get; set; 
        public bool IsDefault  get; set; 
        public virtual List<Contacts> Contacts  get; set; 

        public int CustomerID  get; set; 
        public virtual Customer Customer  get; set; 
    

    public class Contacts
    
        [Key]
        public int ContactID  get; set; 

        public string Phone  get; set; 
        public string Fax  get; set; 
        public bool IsDefault  get; set; 

        public int AddressID  get; set; 
        public virtual Addresses Customer  get; set;  

    

    public class TestDBContext : DbContext
    
        public TestDBContext()
            : base("name=TestDBContext")
        
        

        public DbSet<Customer> Customer  get; set; 
        public DbSet<Addresses> Addresses  get; set; 
        public DbSet<Contacts> Contacts  get; set; 
    

当我像下面的查询一样查询客户时,EF 在幕后的 db 中创建所有必需的表。

var bsCustomer = (from cu in db.Customer
  where (cu.CustomerID == 2)
  select new
  
      cu,
      Addresses = from ad in cu.Addresses
          where (ad.IsDefault == true)
          from ct in ad.Contacts
          select ad,

  ).ToList();

稍后我在 db 中创建一个视图,并在下面的代码中引用该视图。

public partial class vwCustomer

    [Key]
    public int CustomerID  get; set; 

    public string FirstName  get; set; 


   public class vwCustomerConfiguration : EntityTypeConfiguration<vwCustomer>
    
        public vwCustomerConfiguration()
        
            this.HasKey(t => t.CustomerID);
            this.ToTable("vwCustomers");
        
    

所以现在我的 DbContext 如下所示,带有视图类参考

public class TestDBContext : DbContext

    public TestDBContext()
        : base("name=TestDBContext")
    
    

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.Configurations.Add(new vwCustomerConfiguration());
    

    public DbSet<Customer> Customer  get; set; 
    public DbSet<Addresses> Addresses  get; set; 
    public DbSet<Contacts> Contacts  get; set; 
    public virtual DbSet<vwCustomer> vwCustomers  get; set; 

在我尝试查询视图时发生错误

using (var db = new TestDBContext())

    var listMyViews = db.vwCustomers.ToList();

错误是Additional information: The model backing the 'TestDBContext' context has changed since the database was created. Consider using Code First Migrations to update the database

谢谢

【问题讨论】:

你能给我们看代码吗? @Sampath 此处显示完整代码。 @Sampath 查看我更新的代码并查看我的答案。谢谢 【参考方案1】:

我们可以通过另一种方式来解决我的问题。看代码。

protected override void OnModelCreating(DbModelBuilder modelBuilder)

    Database.SetInitializer<YourDbContext>(null);
    base.OnModelCreating(modelBuilder);

代码取自这里https://***.com/a/6143116/6188148

我们也可以采用这种方法。

public partial class AddingvwCustomer : DbMigration
    
        public override void Up()
        

        

        public override void Down()
        
        
    

我想这也可以,但我自己没有测试过。

我们可以使用 Fluent API 使用 Ignore 方法对其进行配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)

    modelBuilder.Ignore<MyClass>();

【讨论】:

如果您想使用迁移系统来更新数据库架构,那么您的方法会遇到问题。如果您仅手动或使用 sql 脚本更新您的数据库,那么它是非常好的。 @mr100 是的,您有权获得第一个答案或第一组代码。我再次更新了答案。【参考方案2】:

像往常一样添加新迁移,并从 Up(和 Down)方法中的迁移代码中删除尝试手动创建新表的代码(在 Up 中调用 CreateTable 方法,在 Down 中调用 DropTable 方法)。然后将迁移应用到您的数据库,一切正常。

不幸的是,自动迁移生成不是非常智能的工具,并且经常需要手动指定应该如何更改数据库。在 EF 迁移的文档中指出,手动编辑迁移代码是完全可以的。

【讨论】:

以上是关于EF 代码首先告诉我对已经在 db 中的 db 对象进行迁移的主要内容,如果未能解决你的问题,请参考以下文章

无法首先在表 ef6 db 中插入标识列的显式值

使用 EF CodeF 和 mvc nugget Scaffold 发布后向 DB 添加列

EF Core中的DB First与Code First

EF 7 中的 db.database.ExecuteSQLCommand 等效项

在此示例中,如何强制 EF 仅更新 Db 中的一列?

EF中三大开发模式之DB First,Model First,Code First以及在Production Environment中的抉择