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

时间:2016-09-13 08:54:37

标签: entity-framework ef-code-first

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

附加信息:支持' TestDBContext'自创建数据库以来,上下文已更改。请考虑使用“代码优先迁移”来更新数据库

我知道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

感谢

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

我们可以采用另一种方式来解决我的问题。看到代码。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    Database.SetInitializer<YourDbContext>(null);
    base.OnModelCreating(modelBuilder);
}

代码来自https://stackoverflow.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>();
}