EF5 Получение этого сообщения об ошибке: Невозможно проверить совместимость модели, поскольку база данных не содержит метаданных модели.

У меня есть это сообщение об ошибке, которое отображается при каждом запуске приложения. Я использую Entity Framework 5: Code First

Вот сообщение об ошибке,

System.NotSupportedException: Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations.
   at System.Data.Entity.Internal.ModelCompatibilityChecker.CompatibleWithModel(InternalContext internalContext, ModelHashCalculator modelHashCalculator, Boolean throwIfNoMetadata)
   at System.Data.Entity.Internal.InternalContext.CompatibleWithModel(Boolean throwIfNoMetadata)
   at System.Data.Entity.Database.CompatibleWithModel(Boolean throwIfNoMetadata)
   at System.Data.Entity.DropCreateDatabaseIfModelChanges`1.InitializeDatabase(TContext context)
   at System.Data.Entity.Database.<>c__DisplayClass2`1.<SetInitializerInternal>b__0(DbContext c)
   at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6()
   at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
   at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
   at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
   at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
   at System.Data.Entity.Internal.InternalContext.Initialize()
   at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
   at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
   at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
   at System.Data.Entity.DbSet`1.Add(TEntity entity)
   at LaundryService_DEMO.frmMain.btnCreate_Click(Object sender, EventArgs e) in d:\MyDocs\Visual Studio 2012\Projects\LaundryService_DEMO\LaundryService_DEMO\frmMain.cs:line 39

Эта ошибка началась, когда я создал объект с именем invoice. Вот полный код объекта,

public class Invoice
{
    public string InvoiceID { get; set; }
    public string CustomerID { get; set; }
    public string UserID { get; set; }
    public decimal TotalAmount { get; set; }
    public DateTime TransactionDate { get; set; }
    public DateTime PaymentDate { get; set; }

    public Customer CustomerField { get; set; }
    public SystemUser SystemUserField { get; set; }
}

public class InvoiceMap : EntityTypeConfiguration<Invoice>
{
    public InvoiceMap()
    {
        // Primary Key
        this.HasKey(x => x.InvoiceID);

        // Property(ies) and Mapping(s)
        this.ToTable("Invoice");

        this.Property(x => x.InvoiceID)
            .IsRequired()
            .HasMaxLength(15)
            .HasColumnName("InvoiceID")
            .HasColumnType("nVarchar");

        this.Property(x => x.CustomerID)
            .IsRequired()
            .HasMaxLength(15)
            .HasColumnName("CustomerID")
            .HasColumnType("nVarchar");

        this.Property(x => x.UserID)
            .IsRequired()
            .HasMaxLength(15)
            .HasColumnName("UserID")
            .HasColumnType("nVarchar");

        this.Property(x => x.TotalAmount)
            .IsRequired()
            .HasColumnName("TotalAmount")
            .HasColumnType("decimal");

        this.Property(x => x.TransactionDate)
            .IsRequired()
            .HasColumnName("TransactionDate")
            .HasColumnType("datetime");

        this.Property(x => x.PaymentDate)
            .IsOptional()
            .HasColumnName("PaymentDate")
            .HasColumnType("datetime");

        // Relationship
        this.HasRequired(x => x.CustomerField)
            .WithMany(x => x.InvoiceCollection)
            .HasForeignKey(y => y.CustomerID);

        this.HasRequired(x => x.SystemUserField)
            .WithMany(x => x.InvoiceCollection)
            .HasForeignKey(y => y.UserID);
    }
}

Для того, чтобы скопировать приложение, я включил файл проекта, который доступен для скачивания. И поэтому этот вопрос не будет полон кода.

Если есть какие-то детали, которые я пропустил в вопросе, пожалуйста, прокомментируйте, чтобы я мог их включить.

8 ответов

Решение

Я нашел код работает, изменив

static LaundryShopContext()
{
  Database.SetInitializer<LaundryShopContext>(
    new DropCreateDatabaseIfModelChanges<LaundryShopContext>());
}

в

static LaundryShopContext()
{
  Database.SetInitializer<LaundryShopContext>(
    new DropCreateDatabaseAlways<LaundryShopContext>());
}

Вероятно, это связано с тем, что ваша база данных не содержит таблицу _MigrationHistory (которую можно просмотреть с помощью SQL Server Management Studio в разделе "Таблицы"> "Системные таблицы").

Не уверен, как вы управляете базой данных, но если вы все еще в разработке и используете EF Migrations, быстрое решение состоит в том, чтобы удалить базу данных и запустить Update-Database, которая воссоздаст всю базу данных и добавит таблицу _MigrationHistory.

Если вы хотите, чтобы EF не выполнял эту проверку, вы можете добавить ее в свой класс DbContext.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}

Если, как и я, это вызвано тем, что вы начинаете с Code First и переходите на промежуточный проект разработки Database First... это все из-за одной простой строки. Если вам нужно сохранить базу данных и ее данные, закомментируйте следующую строку:

Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());

из этого раздела вашей модели.

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }
    static ApplicationDbContext()
    {
        // Set the database intializer which is run once during application start
        // This seeds the database with admin user credentials and admin role
        //   Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

Это часто случается, когда вы начинаете со встроенными моделями идентичности. Как только вы заставите их работать, вы можете удалить эту строку, чтобы сохранить ее в целости и сохранении функциональности. Однако, если ваша модель изменится, ваша база данных должна быть настроена так, чтобы соответствовать... что-то, что вы в любом случае делаете в Database First!

Это также может произойти, если вы пытаетесь инициализировать контекст для ранее существующей базы данных с тем же именем, но созданной с другой кодовой базой. Вот почему смена DropCreateDatabaseIfModelChanges на DropCreateDatabaseAlways работает, последняя конфигурация приводит к воссозданию базы данных, несмотря ни на что, в обход любого вида управления версиями базы данных, который может вызывать эту проблему.

Я знаю, что опоздал на вечеринку, но я только что столкнулся с той же ошибкой, и в моей базе данных уже была таблица истории миграции.

Ошибка также может указывать на неверный ключ контекста в таблице истории. Это может произойти, если вы переместите класс контекста базы данных в другое пространство имен, как я сделал во время рефакторинга.

Обновление ContextKey значение в MigrationHistory Таблица с новым пространством имен контекста базы данных исправила проблему для меня.

Это решение не требует от вас отбрасывать содержимое базы данных, поэтому может быть предпочтительнее, чем DropCreateDatabaseAlways решение.

Я попробовал ниже 3 шага. Это работает для меня.. Запустите следующие команды в консоли диспетчера пакетов 1. enable-migrations 2. update-database -verbose 3. add-migration initialmigrations -ignorechanges

ПРИМЕЧАНИЕ. Мой сценарий: я уже создал таблицы db/ (используя подход "сначала код" (используя общую библиотеку контекста БД). Я пытаюсь использовать библиотеку в другом приложении и другой базе данных. Я вручную синхронизировал первый БД со вторым... вот и все). почему я столкнулся с этой проблемой.

Я получил эту ошибку, когда я добавляю
ContextKey = "MyProject.Repository.Common.DbContextA";

в Configuration.cs. После удаления этой строки все работает.

CreateDatabaseIfNotExists<ApplicationDbContext>();
Другие вопросы по тегам