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中遇到幾個問題

表結構:

操作

1.構造數據對象

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.構造DBContext

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.生成數據

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);
                }
            }
        }

 

做到這里,認為就能成功運行插入新的產品,簡直太天真了。

 

問題一,無法連接數據庫,對象模型不存在:

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

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");
            });
        }

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM