The model backing the 'ProductContext' context has changed since the database was created. EF6

學習《Entity Framework 6 Recipes 2nd Edition》,2-6. Splitting an Entity Among Multiple Tables中遇到幾個問題數據庫

表結構:ide

操做學習

1.構造數據對象ui

public class Product
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int SKU { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public string ImageURL { get; set; }
    }

2.構造DBContextthis

public class ProductContext:DbContext
    {
        public DbSet<Product> Products { get; set; }
        public ProductContext()
            : base("name=EF6CodeFirstRecipesContext")
        {
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Product>()
            .Map(m =>
            {
                m.Properties(p => new { p.SKU, p.Description, p.Price });
                m.ToTable("Product", "Chapter2");
            })
            .Map(m =>
            {
                m.Properties(p => new { p.SKU, p.ImageURL });
                m.ToTable("ProductWebInfo", "Chapter2");
            });
        }
    }

3.生成數據spa

public static void InsertProduct()
        {
            //Database.SetInitializer<ProductContext>(null);

            using (var context = new ProductContext())
            {
                var product = new Product
                {
                    SKU = 147,
                    Description = "Expandable Hydration Pack",
                    Price = 19.97M,
                    ImageURL = "/pack147.jpg"
                };
                context.Products.Add(product);
                product = new Product
                {
                    SKU = 178,
                    Description = "Rugged Ranger Duffel Bag",
                    Price = 39.97M,
                    ImageURL = "/pack178.jpg"
                };
                context.Products.Add(product);
                product = new Product
                {
                    SKU = 186,
                    Description = "Range Field Pack",
                    Price = 98.97M,
                    ImageURL = "/noimage.jp"
                };
                context.Products.Add(product);
                product = new Product
                {
                    SKU = 202,
                    Description = "Small Deployment Back Pack",
                    Price = 29.97M,
                    ImageURL = "/pack202.jpg"
                };
                context.Products.Add(product);
                context.SaveChanges();
            }
            using (var context = new ProductContext())
            {
                foreach (var p in context.Products)
                {
                    Console.WriteLine("{0} {1} {2} {3}", p.SKU, p.Description,
                    p.Price.ToString("C"), p.ImageURL);
                }
            }
        }

 

作到這裏,認爲就能成功運行插入新的產品,簡直太天真了。3d

 

問題一,沒法鏈接數據庫,對象模型不存在:code

An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dllorm

Additional information: The entity type Product is not part of the model for the current context.對象

 

解決辦法:

木有仔細研究,試驗了一下,發現是App.config中DB鏈接串的問題

原來的連接串:

<add name="EF6RecipesContext" connectionString="metadata=res://*/TestModel.csdl|res://*/TestModel.ssdl|res://*/TestModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=DST60519\SQLEXPRESS;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

修改後的鏈接串:

<add name="EF6CodeFirstRecipesContext" providerName="System.Data.SqlClient" connectionString="Data Source=DST60519\SQLEXPRESS;Initial Catalog=TestDB;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFramework"/>

EF生成連接串是  providerName="System.Data.EntityClient"

而CodeFirst生成串是  providerName="System.Data.SqlClient"

 

修改後就能夠了?太天真!

 

問題二,DbContext生成異常:

通過修改後運行,發現仍是會報錯

The model backing the 'ProductContext' context has changed since the database was created.

Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

 

查一下網上的資料:

For those who are seeing this exception:

"The model backing the 'Production' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance."

Here is what is going on and what to do about it:

When a model is first created, we run a DatabaseInitializer to do things like create the database if it's not there or add seed data. The default DatabaseInitializer tries to compare the database schema needed to use the model with a hash of the schema stored in an EdmMetadata table that is created with a database (when Code First is the one creating the database). Existing databases won’t have the EdmMetadata table and so won’t have the hash…and the implementation today will throw if that table is missing. We'll work on changing this behavior before we ship the fial version since it is the default. Until then, existing databases do not generally need any database initializer so it can be turned off for your context type by calling:

Database.SetInitializer<YourDbContext>(null);
(http://stackoverflow.com/questions/3600175/the-model-backing-the-database-context-has-changed-since-the-database-was-crea)

因此說,在使用數據的時候,就要先戳一下鏈接串,告訴它咱們要來了,在使用前加上:Database.SetInitializer<ProductContext>(null);

 

而後就能夠走通了,yeah!

 

可是報了個錯:

Violation of PRIMARY KEY constraint 'PK_Chapter2.Product'.
Cannot insert duplicate key in object 'Chapter2.Product'. The duplicate key value is (147).
The statement has been terminated.

 

緣由待查ing

 

EF好難搞!!!

 

2015-8-19 14:05:52 接上

 

問題解決,

源碼ProductContext:DbContext中的

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Product>()
            .Map(m =>
            {
                m.Properties(p => new { p.SKU, p.Description, p.Price });
                m.ToTable("Product", "Chapter2");
            })
            .Map(m =>
            {
                m.Properties(p => new { p.SKU, p.ImageURL });
                m.ToTable("ProductWebInfo", "Chapter2");
            });
        }

改成

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Product>()
            .Map(m =>
            {
                m.Properties(p => new { p.SKU, p.Description, p.Price });
                m.ToTable("Product");
                //m.ToTable("Product");
            })
            .Map(m =>
            {
                m.Properties(p => new { p.SKU, p.ImageURL });
                m.ToTable("ProductWebInfo");
                //m.ToTable("ProductWebInfo");
            });
        }

就能夠了,就這樣吧,有空再深究吧_(:з」∠)_

相關文章
相關標籤/搜索