โมเดลที่สำรองข้อมูลบริบท <Database> นั้นเปลี่ยนไปนับตั้งแต่สร้างฐานข้อมูล


253

ข้อความแสดงข้อผิดพลาด:

"โมเดลที่สำรองข้อมูลบริบท 'AddressBook' มีการเปลี่ยนแปลงนับตั้งแต่ฐานข้อมูลถูกสร้างขึ้นด้วยตนเองลบ / อัปเดตฐานข้อมูลด้วยตนเองหรือโทร Database.SetInitializer ด้วยอินสแตนซ์ IDatabaseInitializer เลือกที่จะปลูกด้วยข้อมูลใหม่ "

ฉันกำลังพยายามใช้คุณสมบัติรหัสแรกและต่อไปนี้คือสิ่งที่ฉันเขียน:

var modelBuilder = new ModelBuilder();
var model = modelBuilder.CreateModel();
using (AddressBook context = new AddressBook(model))
{
    var contact = new Contact
    {
        ContactID = 10000,
        FirstName = "Brian",
        LastName = "Lara",
        ModifiedDate = DateTime.Now,
        AddDate = DateTime.Now,
        Title = "Mr."

    };
    context.contacts.Add(contact);
    int result = context.SaveChanges();
    Console.WriteLine("Result :- "+ result.ToString());
}

คลาสบริบท:

public class AddressBook : DbContext
{
    public AddressBook()
    { }
    public AddressBook(DbModel AddressBook)
        : base(AddressBook)
    {

    }
    public DbSet<Contact> contacts { get; set; }
    public DbSet<Address> Addresses { get; set; }
}

และสตริงการเชื่อมต่อ:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <connectionStrings>
    <add name="AddressBook" providerName="System.Data.SqlClient"  
         connectionString="Data Source=MyMachine;Initial Catalog=AddressBook;
         Integrated Security=True;MultipleActiveResultSets=True;"/>
    </connectionStrings>
</configuration>

ดังนั้นชื่อฐานข้อมูลคือ "AddressBook" และข้อผิดพลาดเกิดขึ้นเมื่อฉันพยายามเพิ่มวัตถุติดต่อไปยังบริบท ฉันไม่มีอะไรที่นี่หรือ



ลบตาราง __MigrationHistory ออกจากฐานข้อมูลของคุณ
Zahid Hasan

คำตอบ:


397

ตอนนี้มันเป็น:

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

ในไฟล์ YourDbContext.cs ของคุณ


ฉันเปลี่ยนฐานข้อมูลการผลิตด้วยตนเองและปิดการย้ายข้อมูลและทำงานได้ดีขอบคุณ
Mohsen Afshin

13
ป.ล. นี้ไปใน Global.asax Application_Start ()
BritishDeveloper

48
ดีกว่า Global.asax คือใส่สิ่งนี้ลงใน Constructor ของคลาส DbContext ของคุณ วิธีนี้ใช้ได้กับทุกไซต์ที่ใช้บริบทแทนที่จะเป็นเพียงไซต์เดียวที่ควบคุมโดยไฟล์ Global.asax
Corin

7
น่าจะดีที่สุดที่จะวางไว้ในตัวสร้างแบบคงที่ของคลาสบริบทดังนั้นจึงเรียกเพียงครั้งเดียว - ในวิดีโอตัวอย่างนี้: msdn.microsoft.com/en-us/data/jj572367
Christian Fredh

3
มันควรจะอยู่ในโมฆะการป้องกันการป้องกันเป็นโมฆะ OnModelCreating (DbModelBuilder modelBuilder) {Database.SetInitializer <YourDbContext> (null); base.OnModelCreating (modelBuilder); }
Chris Voon

135

นี่คือข้อมูลบางส่วนจากบล็อกของ Scott Gu ที่โพสต์โดยJeffเกี่ยวกับสิ่งที่เกิดขึ้นจริง:

สำหรับผู้ที่เห็นข้อยกเว้นนี้:

"โมเดลที่สนับสนุนบริบท 'การผลิต' มีการเปลี่ยนแปลงนับตั้งแต่สร้างฐานข้อมูลอาจลบ / อัพเดตฐานข้อมูลด้วยตนเองหรือโทรDatabase.SetInitializerด้วยIDatabaseInitializerอินสแตนซ์"

นี่คือสิ่งที่เกิดขึ้นและจะทำอย่างไรกับมัน:

เมื่อสร้างแบบจำลองเป็นครั้งแรกเราจะเรียกใช้ DatabaseInitializer เพื่อทำสิ่งต่าง ๆ เช่นสร้างฐานข้อมูลหากไม่มีหรือเพิ่มข้อมูลเมล็ด DatabaseInitializer เริ่มต้นพยายามที่จะเปรียบเทียบสกีมาฐานข้อมูลที่จำเป็นในการใช้โมเดลที่มีแฮชของสกีมาที่เก็บไว้ในตาราง EdmMetadata ที่สร้างขึ้นด้วยฐานข้อมูล (เมื่อรหัสแรกคือฐานข้อมูลที่สร้าง) ฐานข้อมูลที่มีอยู่จะไม่มีตาราง EdmMetadata ดังนั้นจะไม่มีแฮช…และการติดตั้งในวันนี้จะเกิดขึ้นหากโต๊ะนั้นหายไป เราจะพยายามแก้ไขพฤติกรรมนี้ก่อนที่เราจะส่งเวอร์ชั่น fial เนื่องจากเป็นค่าเริ่มต้น ก่อนหน้านั้นฐานข้อมูลที่มีอยู่ไม่จำเป็นต้องมี initializer ฐานข้อมูลใด ๆ เพื่อให้สามารถปิดใช้งานได้กับชนิดบริบทของคุณโดยการโทร:

Database.SetInitializer<YourDbContext>(null);

เจฟฟ์


9
ฉันลองวันนี้และฉันไม่ได้รับ "โมเดลมีการเปลี่ยนแปลง" แต่ฉันจะได้รับ "ชื่อวัตถุไม่ถูกต้อง 'dbo.Table'"
Stefan Bergfeldt

3
เจฟฟ์ต้องการให้สิ่งนี้เป็นวิธีแก้ปัญหา แต่มันก็เป็นเวลานานกว่าสองปีแล้วและ SetInitializer to null นั้นยังจำเป็น ขวา? ดังนั้นใครบางคนได้โปรดอธิบายว่าสิ่งนี้เหมาะกับกระบวนการโยกย้าย
kroiz

2
@jakejgordon: ฉันก็มี EF6 เหมือนกัน แต่ถ้าอยู่ใน Global.asax มันจะแก้ไขปัญหาเฉพาะเมื่อใช้งานเว็บไซต์ หากคุณมีการทดสอบหน่วยคุณเป็น OOL ดีกว่าที่จะวางไว้ในตัวสร้างของ YourDbContext ที่แก้ไขสำหรับทุกโครงการรวมถึงเว็บไซต์และทดสอบโครงการ
Rap

1
IMO คำตอบนี้ควรจะได้คะแนนสูงกว่าเพราะจริง ๆ แล้วอธิบายว่าทำไมเราต้องเพิ่มรหัสบรรทัดนี้ ขอบคุณ.
พอล

1
@StefanBergfeldt หากคุณหรือใครก็ตามได้รับการInvalid object name 'dbo.Tableตรวจสอบสตริงการเชื่อมต่อของคุณแนบ DBFilename และแคตตาล็อกเริ่มต้น
benscabbia

41

สำหรับEntity Framework 5.0.0.0 - 6.1.3

คุณไม่แน่นอนต้องการที่จะทำต่อไปนี้:

1. using System.Data.Entity;   to startup file (console app --> Program.cs / mvc --> global.asax
2. Database.SetInitializer<YourDatabaseContext>(null);

ใช่ Matt Frear ถูกต้อง อัพเดท -EDIT: Caveat คือฉันเห็นด้วยกับคนอื่น ๆ ในนั้นแทนที่จะเพิ่มรหัสนี้ไปยัง global.asax ที่เพิ่มในคลาส DbContext ของคุณ

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // other code 
    Database.SetInitializer<YOURContext>(null);
    // more code here.
}

อย่างที่คนอื่น ๆ พูดถึงมันก็ดีสำหรับการจัดการหน่วยทดสอบ

ขณะนี้ฉันกำลังใช้สิ่งนี้กับ Entity Framework 6.1.3 /.net 4.6.1

ฉันจะกลับมาให้ข้อมูลตัวอย่าง CORE ในอนาคตอันใกล้


1
ขอบคุณ! Program.cs ใช้งานได้กับคอนโซลอย่างแน่นอน
HockeyJ

แต่เมื่อคุณเริ่มต้นฐานข้อมูลของคุณเป็นครั้งแรกมันจะไม่สร้างฐานข้อมูลถ้าฉันใส่ setinitializer null ที่เมธอด onModelCreating ความคิดใด ๆ เหตุการณ์ฉันใช้ (var context = Activator.CreateInstance <TContext> ()) {context.Database.Initialize (true); }
Rupesh Kumar Tiwari

ฉันจำเป็นต้องค้นหารหัสของฉันที่ฉันจะใช้ในบางครั้งฉันจะแสดงความคิดเห็นออกบรรทัดและสลับ ... ฉันจำไม่ได้ว่าปัญหาฉันต้องมอง
Tom Stickel

1
ทางออกที่ดีที่สุด มันทำให้การแก้ปัญหาของฉันทำงานและฉันไม่รู้ว่าการแตกกิ่งก้านคืออะไร ยอมรับและปรับใช้
Svend

32

เพียงแค่เรียกใช้คำสั่ง followng sql ใน SQL Server Management Studio:

delete FROM [dbo].[__MigrationHistory]

1
คุณช่วยชีวิตฉัน! ขอบคุณ.
Marek Dorda

31

การแก้ไขนี้ไม่สามารถใช้งานได้หลังจาก CTP5

คุณต้องทำ Database.SetInitializer<YourContext>(null);


1
มันจะไปไหน ... OnModelCreating ไม่มีสิ่งใดที่สามารถเข้าถึงได้เรียกว่า DbDatabase
James Reategui

ที่ไหนสักแห่งในการเริ่มต้นฉันตั้งของฉันใน Application_Start
chrisortman

Database.SetInitializer ดูเหมือนว่าจะทำงานได้ดีในรุ่นสุดท้ายของ EF 4.3
Richard Beier

ฉันคิดว่า "การแก้ไขนี้ไม่สามารถใช้งานได้หลังจาก CTP5" หมายความว่าคำตอบที่ได้รับการยอมรับตั้งแต่วันที่ 30 สิงหาคม 2010 เป็นสิ่งที่เขาพูด
Tom Stickel

19

เพิ่งพบคำตอบและความคิดของการปรับปรุงที่นี่ เพียงแค่ต้องทำสิ่งต่อไปนี้

public class AddressBook: DbContext
{
   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
    modelBuilder.IncludeMetadataInDatabase = false;
   }
}

12
สิ่งนี้ไม่สามารถทำได้กับ EF รุ่นที่ใหม่กว่าอีกทั้งยังmodelBuilder.Conventions.Remove<IncludeMetadataConvention>();ไม่ช่วยสถานการณ์ DbDatabase.SetInitialzer (null); ทำงานได้ดี
JTew

@TomStickel - ฉันเห็นด้วย ทำเครื่องหมายstackoverflow.com/a/6143116/255562เป็นคำตอบ
Ashish Gupta

16

หรือคุณสามารถวางบรรทัดนี้ในไฟล์ Global.asax.cs ของคุณภายใต้ Application_Start ():

System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<ProjectName.Path.Context>());

ตรวจสอบให้แน่ใจว่าได้เปลี่ยน ProjectName.Path.Context เป็นเนมสเปซและบริบทของคุณ หากใช้รหัสก่อนจะเป็นการลบและสร้างฐานข้อมูลใหม่ทุกครั้งที่มีการเปลี่ยนแปลงใด ๆ กับสคีมา


สิ่งที่ฉันต้องการตั้งแต่ฉันทำต้นแบบเท่านั้น ขอบคุณมาก.
ผู้เรียน

8

ฉันใช้เวลาหลายวันเพื่อแก้ไขปัญหานี้วิเคราะห์โพสต์ที่แตกต่างกันจำนวนมากและลองใช้ตัวเลือกมากมายและแก้ไขในที่สุด 2 โครงการนี้ในโซลูชันของฉันโดยใช้การโยกย้ายรหัส EF เป็นครั้งแรก:

  • แอปพลิเคชั่นคอนโซล "DataModel" ซึ่งส่วนใหญ่ใช้เป็นชุดประกอบซึ่งมีรหัสเอนทิตีแรกของฉันทั้งหมดคือ DbContext, Mirgations และพื้นที่เก็บข้อมูลทั่วไป ฉันได้รวมไว้ในโครงการนี้แยกไฟล์ฐานข้อมูลท้องถิ่นที่ว่างเปล่า (ในโฟลเดอร์ DataModel / App_Data) เพื่อให้สามารถสร้างการย้ายข้อมูลจาก Package Manager Console
  • WebApi ซึ่งอ้างอิงถึงโครงการ DataModel และใช้ไฟล์ฐานข้อมูลท้องถิ่นจากโฟลเดอร์ WebApi / App_Data ซึ่งไม่รวมอยู่ในโครงการ

ฉันได้รับข้อผิดพลาดนี้เมื่อร้องขอ WebApi ...

สภาพแวดล้อมของฉัน:

  • Windows 8.1 x64
  • Visual Studio 2015 Professional พร้อมอัปเดต 1
  • โครงการของฉันทั้งหมดกำหนดเป้าหมายสำหรับ. NET Framework 4.6.1
  • EntityFramework 6.1.3 จาก NuGet

ที่นี่ฉันรวบรวมข้อสังเกตทั้งหมดที่คุณควรให้ความสนใจและเงื่อนไข / ข้อกำหนดทั้งหมดที่ต้องปฏิบัติตามเพื่อหลีกเลี่ยงข้อยกเว้นที่กล่าวถึง:

  1. คุณควรใช้แพ็คเกจ EntityFramework Nuget รุ่นเดียวสำหรับทุกโครงการในโซลูชันของคุณ
  2. ฐานข้อมูลที่สร้างขึ้นโดยการเรียกใช้สคริปต์การย้ายข้อมูลทั้งหมดตามลำดับควรมีโครงสร้าง / สคีมาเหมือนกับที่คุณกำหนดเป้าหมายฐานข้อมูลและสอดคล้องกับเอนทิตีโมเดล การติดตาม 3 สิ่งต่อไปนี้จะต้องสอดคล้อง / สะท้อน / จับคู่กัน:
    • สคริปต์การย้ายข้อมูลของคุณทั้งหมดจนถึงล่าสุด
    • รหัสปัจจุบันสถานะรูปแบบเอนทิตีแรก (DbContext, เอนทิตี)
    • ฐานข้อมูลเป้าหมาย
  3. ฐานข้อมูลเป้าหมาย (ไฟล์ mdf) ควรได้รับการอัปเดต / สอดคล้องกับสคริปต์การย้ายข้อมูลล่าสุด ตรวจสอบว่าตาราง "__MigrationHistory" ในฐานข้อมูลเป้าหมายของคุณมีระเบียนสำหรับสคริปต์การย้ายข้อมูลทั้งหมดที่คุณมีหมายความว่าสคริปต์การย้ายข้อมูลทั้งหมดถูกนำไปใช้กับฐานข้อมูลนั้นสำเร็จ ฉันขอแนะนำให้คุณใช้ Visual Studio สำหรับการสร้างรหัสที่ถูกต้องก่อนหน่วยงานและบริบทที่สอดคล้องกับฐานข้อมูลของคุณโครงการ -> เพิ่มรายการใหม่ -> ADO.NET Entity Data Model -> รหัสแรกจากฐานข้อมูล: แน่นอนว่าเป็นทางเลือกถ้า คุณไม่มีฐานข้อมูลคุณสามารถเขียนแบบจำลองด้วยตนเอง (รหัสเอนทิตีและบริบทแรก) จากนั้นสร้างการย้ายข้อมูลเริ่มต้นและฐานข้อมูล
  4. ชื่อของสตริงการเชื่อมต่อเช่นMyConnectionStringในไฟล์กำหนดค่าของโครงการเริ่มต้น (Web.config / App.config):

    <configuration>
      <connectionStrings>
        <add name="MyConnectionString" connectionString="...">
      </connectionStrings>
    <configuration>

    ควรเท่ากับพารามิเตอร์ที่ส่งผ่านใน Constructor ของ DbContext ของคุณ:

     public partial class MyDbContext : DbContext
     {
        public MyDbContext()
           : base("name=MyConnectionString"){}
        ...
  5. ก่อนที่จะใช้Package Manager Consoleตรวจสอบให้แน่ใจว่าคุณใช้ฐานข้อมูลที่ถูกต้องสำหรับการอัพเดตหรือสร้างการย้ายข้อมูลและโครงการที่จำเป็นถูกตั้งค่าเป็นโครงการเริ่มต้นของโซลูชัน สำหรับการเชื่อมต่อกับฐานข้อมูลมันจะใช้สตริงการเชื่อมต่อจากไฟล์. config ซึ่งในโปรเจ็กต์ซึ่งถูกตั้งค่าเป็นโปรเจ็กต์เริ่มต้น
  6. และหลักซึ่งแก้ไขปัญหาของฉัน:มันแปลก แต่ในโฟลเดอร์ WebApi / bin DataModel.exe ของฉันเก่าไม่รีเฟรชตั้งแต่การสร้างครั้งล่าสุด เนื่องจากการย้ายข้อมูลถูกฝังอยู่ในชุดประกอบ DataModel.exe ของฉันดังนั้นฐานข้อมูล WebApi ที่อัปเดตของฉันจึงใช้ mirgations เก่า ฉันสับสนว่าทำไมหลังจากอัปเดตฐานข้อมูลใน WebApi มันไม่สอดคล้องกับสคริปต์การย้ายข้อมูลล่าสุดจาก DataModel รหัสต่อไปนี้จะสร้างขึ้นโดยอัตโนมัติ (หากไม่มี) หรืออัปเดตฐานข้อมูลท้องถิ่นการโยกย้ายล่าสุดในโฟลเดอร์ WebApi / App_Data ของฉัน

       public class WebApiApplication : System.Web.HttpApplication
       {
           protected void Application_Start()
           {
               Database.SetInitializer(new MigrateDatabaseToLatestVersion<ODS_DbContext, Configuration>()); 
               ...

    ฉันพยายามทำความสะอาดและสร้างโซลูชันขึ้นมาใหม่ แต่ไม่ได้ช่วยอะไรฉันลบโฟลเดอร์ bin และ obj ออกจาก WebApi โดยสมบูรณ์ลบไฟล์ฐานข้อมูลจาก WebApi / App_Data สร้างขึ้นเริ่ม WebApi ใหม่สร้างคำขอใหม่สร้างฐานข้อมูลที่ถูกต้อง - การเริ่มต้นขี้เกียจ (โดยใช้ บรรทัดด้านบน) ซึ่งสอดคล้องกับการโยกย้ายล่าสุดและข้อยกเว้นไม่ปรากฏขึ้นอีก ดังนั้นสิ่งนี้อาจแก้ไขปัญหาของคุณ:

    1. ลบ bin ด้วยตนเอง, obj โฟลเดอร์จากโครงการเริ่มต้นของคุณ (ซึ่งสร้าง / อัพเดทฐานข้อมูลของคุณ)
    2. สร้างโครงการเริ่มต้นของคุณหรือดีกว่าสะอาดและสร้างโซลูชันทั้งหมดของคุณใหม่
    3. สร้างฐานข้อมูลใหม่โดยเริ่มต้นโครงการ (จะเรียกใช้งานบรรทัดด้านบน) หรือใช้คำสั่ง "Update-database" Console Package
    4. ตรวจสอบด้วยตนเองว่า db ที่สร้างขึ้นและ __MirgationHistory สอดคล้องกับสคริปต์การย้ายข้อมูลล่าสุดหรือไม่

5

สำหรับฉันด้วยการอัปเกรดเป็น 4.3.1 ฉันเพิ่งตัดทอนตาราง EdmMetaData หรือลบออกทันที


ฉันอัปเดตเป็น 4.3.1 แล้วเปลี่ยนชื่อเป็นตาราง EdmMaetaData ตอนนี้ฉันสามารถเปลี่ยนแปลงรูปแบบได้ตามต้องการและไม่มีข้อความแสดงข้อผิดพลาดที่น่ารำคาญเกี่ยวกับตัวแบบจำลองสำรอง blah blah
Ashok Padmanabhan

3

สำหรับนักพัฒนา VB.NET:

เพิ่มบรรทัดต่อไปนี้ในไฟล์ Glabal.asax.vb ที่ส่วนท้ายของเมธอด Application_Start ()

Database.SetInitializer(Of ApplicationDbContext)(Nothing)

เปลี่ยน ApplicationDbContext เป็นบริบท Db เฉพาะของคุณ


2

ฉันมีปัญหานี้และพบว่าโครงการหนึ่งชี้ไปที่ SQLExpress แต่โครงการที่มีปัญหาชี้ไปที่ LocalDb (ใน web.config นั้น ๆ ) การตรวจสอบที่โง่เง่า แต่ควรสังเกตที่นี่ในกรณีที่คนอื่นกำลังแก้ไขปัญหานี้


2

หมายความว่ามีการเปลี่ยนแปลงบางอย่างในบริบทที่ยังไม่ได้ดำเนินการ โปรดเรียกใช้ Add-Migration ก่อนเพื่อสร้างการเปลี่ยนแปลงที่เราทำ (การเปลี่ยนแปลงที่เราอาจไม่ทราบ) จากนั้นเรียกใช้ Update-Database


2

ฉันมีปัญหาเดียวกัน - การเพิ่มการย้ายข้อมูลใหม่และการอัปเดตฐานข้อมูลไม่ทำงานและไม่มีคำตอบใด ๆ ข้างต้นดูเหมือนถูกต้อง จากนั้นแรงบันดาลใจก็มาถึงฉัน - ฉันใช้หลายระดับ (เว็บเดียวหนึ่งข้อมูลและธุรกิจเดียว) ชั้นข้อมูลมีบริบทและทุกรุ่น เลเยอร์เว็บไม่เคยโยนข้อยกเว้นนี้ - มันเป็นเลเยอร์ธุรกิจ (ซึ่งฉันตั้งเป็นแอปพลิเคชันคอนโซลสำหรับการทดสอบและการดีบัก) กลับกลายเป็นว่าเลเยอร์ธุรกิจไม่ได้ใช้สตริงการเชื่อมต่อที่ถูกต้องเพื่อรับ db และสร้างบริบท ดังนั้นฉันจึงเพิ่มสตริงการเชื่อมต่อไปยังการกำหนดค่าแอพของชั้นธุรกิจ (และชั้นข้อมูล) และใช้งานได้ดี วางสิ่งนี้ไว้ที่นี่เพื่อคนอื่นที่อาจประสบปัญหาเดียวกัน


1

ฉันใช้เมธอด Database.CompatibleWithModel (มีอยู่ใน EF5) เพื่อทดสอบว่ารุ่นและฐานข้อมูลตรงกันก่อนที่ฉันจะใช้หรือไม่ ฉันเรียกวิธีนี้หลังจากสร้างบริบท ...

        // test the context to see if the model is out of sync with the db...
        if (!MyContext.Database.CompatibleWithModel(true))
        {
            // delete the old version of the database...
            if (File.Exists(databaseFileName))
                File.Delete(databaseFileName);
            MyContext.Database.Initialize(true);

            // re-populate database

        }

1

ข้อเสนอแนะที่ดี แต่ไม่แม่นยำในทุกกรณี ฉันคิดออกหนึ่ง โปรดคุณต้องตรวจสอบให้แน่ใจว่าคุณเรียกใช้ "enable-migrations" โดยใช้ PM windows ใน Visual Studio และโฟลเดอร์ Migration จะถูกเพิ่มเข้าในโครงการของคุณ

ตรวจสอบให้แน่ใจว่าไฟล์คลาส c # สองไฟล์ที่เพิ่มลงในโฟลเดอร์นั้นมีทุกรุ่นและคุณสมบัติที่เกี่ยวข้อง

หากคุณมีทั้งหมดที่สร้างโซลูชันและ publis สำหรับการปรับใช้

เหตุผลคือเมตาดาต้าที่มีอยู่ไม่สามารถเขียนทับได้เนื่องจากแอปพลิเคชันของคุณไม่มีเมทาดาทาที่จะแทนที่ปัจจุบัน เป็นผลให้คุณได้รับข้อผิดพลาดนี้ "รูปแบบการสำรองบริบทมีการเปลี่ยนแปลงตั้งแต่สร้างฐานข้อมูล"


1

ในกรณีที่บางคนมีสถานการณ์แบบเดียวกันกับฉัน

ฉันมีฐานข้อมูล EF เป็นครั้งแรกและในเวลาเดียวกันโดยใช้ identity asp.net

ดังนั้นฉันจึงมีสอง connectionStrings ใน webconfig ของฉันและไม่มีปัญหากับมัน มันเกิดขึ้นที่ฉันสร้าง / เรียกใช้สคริปต์เพื่อสร้างตารางข้อมูลประจำตัว asp.net ด้วยตนเองซึ่งฉันไม่ควรทำ

ดังนั้น DROP แรกจะเป็นตาราง asp.net ทั้งหมดที่คุณสร้างเอง / จากสคริปต์

DROP TABLE __MigrationHistory
DROP TABLE AspNetRoles
DROP TABLE AspNetUserClaims
DROP TABLE AspNetUserLogins
DROP TABLE AspNetUserRoles
DROP TABLE AspNetUsers

1

ไม่มีวิธีแก้ปัญหาใดที่จะใช้งานได้สำหรับเรา (นอกเหนือจากการปิดใช้งานการตรวจสอบสคีมาทั้งหมด) ในที่สุดเราก็พลาดการแข่งขันในรุ่น Newtonsoft.json ของเรา

AppConfig ของเราไม่ได้รับการอัปเดตอย่างถูกต้อง:

<dependentAssembly>
   <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
  </dependentAssembly>

วิธีแก้ไขคือการแก้ไขเวอร์ชันชุดประกอบให้เป็นรุ่นที่เราใช้งานจริง

<dependentAssembly>
   <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="10.0.0.0" />
  </dependentAssembly>

เรามีปัญหาที่คล้ายกันกับเวอร์ชันของ Newtonsoft.json เมื่อเราอัปเดตเวอร์ชันปัญหาได้รับการแก้ไข
Rui Estreito

0

หลังจากการวิจัยในหัวข้อนี้ฉันพบว่าข้อผิดพลาดเกิดขึ้นโดยทั่วไปถ้าคุณมีตัวอย่างของ db ที่สร้างขึ้นก่อนหน้านี้บนเซิร์ฟเวอร์ sql ด่วนของคุณ ดังนั้นเมื่อใดก็ตามที่คุณมีการปรับปรุงเกี่ยวกับฐานข้อมูลและพยายามที่จะปรับปรุงฐานข้อมูล / เรียกใช้รหัสบางอย่างเกี่ยวกับฐานข้อมูลโดยไม่ต้องใช้Update Databaseคำสั่งการใช้Package Manager Console; ก่อนอื่นคุณต้องลบ db ก่อนหน้านี้บน sql express ของเราด้วยตนเอง

นอกจากนี้โซลูชันนี้ยังใช้งานได้เว้นแต่คุณจะมีAutomaticMigrationsEnabled = false;ในการกำหนดค่าของคุณ

หากคุณทำงานกับระบบควบคุมเวอร์ชัน (git, svn และอื่น ๆ ) และนักพัฒนาอื่น ๆ บางคนอัพเดตวัตถุ db ในขั้นตอนการผลิตข้อผิดพลาดนี้จะเพิ่มขึ้นทุกครั้งที่คุณอัปเดตรหัสฐานและเรียกใช้แอปพลิเคชัน

ตามที่ระบุไว้ข้างต้นมีวิธีแก้ไขปัญหาบางอย่างสำหรับสิ่งนี้ในฐานรหัส อย่างไรก็ตามนี่เป็นวิธีที่ใช้ได้ผลมากที่สุดในบางกรณี


0

ฉันกำลังอ่านหนังสือ Pro ASP.NET MVC 4 เช่นกันและพบปัญหาเดียวกันกับที่คุณมี สำหรับฉันฉันเริ่มมีปัญหาหลังจากทำการเปลี่ยนแปลงที่กำหนดไว้ในส่วน 'การเพิ่มการตรวจสอบรุ่น' ของหนังสือ วิธีที่ฉันแก้ไขปัญหาคือการย้ายฐานข้อมูลของฉันจาก localdb ไปยังเซิร์ฟเวอร์ SQL Server 2012 แบบเต็ม (BTW ฉันรู้ว่าฉันโชคดีที่ฉันสามารถเปลี่ยนเป็นเวอร์ชั่นเต็มได้ดังนั้นอย่าเกลียดฉัน ;-))) ต้องมีบางอย่างที่มีการสื่อสารกับฐานข้อมูลที่เป็นสาเหตุของปัญหา


คุณจะรู้ได้อย่างไรว่ามันเป็นการสื่อสารกับ db และไม่ใช่ตัวอย่างของข้อมูลเมตา
flup

2
ขอโทษที่ตอบช้า. ปรากฎว่าไม่ใช่ปัญหาการสื่อสารเลย! การสร้างฐานข้อมูลใหม่เพียงหลอกลวงปัญหาเพราะฉันได้รับปัญหาเดิมอีกครั้ง! __Migrationxxx (จำไม่ได้ว่าชื่อที่แน่นอนของตารางเพราะฉันเพิ่งลบมัน) ถูกสร้างโดย ef เพียงแค่ลบมันและคุณควรจะดี
J3Speaks

@ MyJ3 ทุกคนพ่นเส้น friggin และบรรทัดของรหัสเหล่านี้ทั้งหมด ทั้งหมดที่ฉันต้องการ! สมควรที่จะได้คำตอบ (สถานการณ์จำลอง)
Terrance00

@ Terrance00 ขอบคุณ!
J3Speaks

0

ตรวจสอบขั้นตอนต่อไปนี้

  1. Database.SetInitializer (null); -> ใน Global.asax.cs

2

  1. ชื่อคลาสบริบทของคุณควรตรงกับตรวจสอบ

0

แก้ไขGlobal.asax.csรวมถึงApplication_Startกิจกรรมด้วย:

Database.SetInitializer<YourDatabaseContext>(
 new DropCreateDatabaseIfModelChanges<YourDatabaseContext>());

5
ฉันจะค่อนข้างชัดเจนเกี่ยวกับสิ่งนี้ทำเอง
Casey

3
ไม่ไม่ไม่ฉันไม่ต้องการใช้ DropCreateDatabase IfModelChanges 99% ของเวลา!
Tom Stickel

0

ข้อผิดพลาดนี้สามารถระบุปัญหากับสตริงการเชื่อมต่อของคุณและว่าชื่อสตริงการเชื่อมต่อของคุณตรงกับการประกาศบริบทฐานข้อมูล

ฉันมีข้อผิดพลาดนี้เพราะฉันได้ตั้งชื่อฐานข้อมูลภายในอย่างไม่ถูกต้อง (ผิดพลาดผิดพลาด) และชื่อของสตริงการเชื่อมต่อใน web.config ของ "DefaultConnection" ไม่ตรงกับ MyDbContext เช่น

public MyDbContext(): base("DefaultConnection")
{}


<connectionStrings>
    <add name="DefaultConnection" ...
  </connectionStrings>

0

ลองใช้ SetInitializer ฐานข้อมูลซึ่งเป็นของใช้ System.Data.Entity;

ใน Global.asax

protected void Application_Start()
{
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<yourContext>());
}

สิ่งนี้จะสร้างฐานข้อมูลใหม่ทุกครั้งที่โมเดลของคุณมีการเปลี่ยนแปลง แต่ฐานข้อมูลของคุณจะว่างเปล่าเพื่อเติมเต็มด้วยข้อมูลจำลองที่คุณสามารถใช้ Seeding ซึ่งคุณสามารถนำไปใช้เป็น:

การเพาะ ::

protected void Application_Start()
{
    Database.SetInitializer(new AddressBookInitializer());
                ----rest code---
}
public class AddressBookInitializer : DropCreateDatabaseIfModelChanges<AddressBook>
{
    protected override void Seed(AddressBook context)
    {
        context.yourmodel.Add(
        {

        });
        base.Seed(context);
    }

}

0

มันแปลก แต่คำตอบทั้งหมดที่นี่ไม่มีประโยชน์สำหรับฉัน สำหรับฉันทำงาน initializer

MigrateDatabaseToLatestVersion

นี่คือวิธีการแก้ปัญหาของฉัน (ฉันรู้ว่ามันง่ายกว่ามาก แต่ก็เป็นวิธีที่ฉันใช้):

class MyDbMigrateToLatest : MigrateDatabaseToLatestVersion<MyDbContext, Configuration>
{
}

public class MyDbContext: DbContext
{
    public MyDbContext() : base("DbName")
    {
        SetInitializer();
    }

    public MyDbContext(string connString) : base(connString)
    {
        SetInitializer();
    }

    private static void SetInitializer()
    {
        if (ConfigurationManager.AppSettings["RebuildDatabaseOnStart"] == "true")
            Database.SetInitializer(new MyDbInitializerForTesting());
        else
            Database.SetInitializer(new MyDbMigrateToLatest());
    }
}

public sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(MyDbContext context)
    {
        // Whatever
    }
}

MyDbInitializerForTesting เพิ่งสืบทอดจาก DropCreateDatabaseAlways ดังนั้นในบางกรณี (การทดสอบ) ฐานข้อมูลทั้งหมดจะถูกสร้างใหม่ มิฉะนั้นจะถูกย้ายไปเป็นเวอร์ชันล่าสุด

แหล่งที่มาของฉัน: https://msdn.microsoft.com/en-us/data/jj591621.aspx#specific


0

ฉันมีปัญหาเดียวกันเมื่อเราใช้ฐานข้อมูลเดียวสำหรับสองแอปพลิเคชัน การตั้งค่าdisableDatabaseInitialization="true"ในส่วนประเภทบริบทใช้งานได้สำหรับฉัน

<entityFramework>
<providers>
  <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
<contexts>
  <context type="PreferencesContext, Preferences" disableDatabaseInitialization="true">
    <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[PreferencesContext, Preferences], [Migrations.Configuration, Preferences]], EntityFramework" />
  </context>
</contexts>

ดูรายละเอียดเพิ่มเติมhttps://msdn.microsoft.com/en-us/data/jj556606.aspx


0

สร้างเครื่องมือเริ่มต้นบริบทที่กำหนดเอง:

public class MyDbContextInitializer : MigrateDatabaseToLatestVersion<MyDbContext, Migrations.Configuration>
{
    public override void InitializeDatabase(MyDbContext context)
    {
        bool exists = context.Database.Exists();

        base.InitializeDatabase(context);

        if (!exists)
        {         
            MyDbSeed.Seed(context);
        }
    }       
}

โปรดสังเกตว่า Migrations.Configuration คือการสร้างคลาสโดยบรรทัดคำสั่งการย้ายใน Package Manager Console คุณอาจต้องเปลี่ยน Internal เป็น Public Modifier ของ Migrations.Configuration class

และลงทะเบียนจาก OmModelCreating ของคุณ:

public partial class MyDbContext : DbContext
{

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<MyDbContext>(new MyDbContextInitializer());

        //other code for creating model
    }
}

-1

ที่นี่ฉันต้องการแบ่งปันวิธีอื่นที่ป้องกันข้อผิดพลาดของการสำรองข้อมูลแบบจำลองเมื่อบริบทเปลี่ยนเป็น:

1) เปิดไฟล์ DbContext ของคุณ

2) เพิ่มเนมสเปซโดยใช้ Microsoft.AspNet.Identity.EntityFramework

3) MyDbContext สาธารณะ (): base ("name = MyDbContext") {Database.SetInitializer (ใหม่ DropCreateDatabaseAlways ()); }

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.