2015-04-25 2 views
1

У меня возникают проблемы с дублирующимися данными во время миграции с помощью Code First.Entity Framework WebAPI Model UpSerts

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

Схемы в базе данных создаются правильно. А именно значения первичных ключей и внешних ключей (последние автоматически генерируются)

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

Например, я вижу мульти запись с тем же приоритетом, где должен быть только 3.

Я использую Entity Framework 6.0.

public class VeloPointDbConfiguration : DbMigrationsConfiguration<VeloPointDbContext> 
{ 
    public VeloPointDbConfiguration() 
    { 
     AutomaticMigrationsEnabled = true; 
     AutomaticMigrationDataLossAllowed = true; 
    } 
    protected override void Seed(VeloPointDbContext context) 
    { 
     context.TaskPriorities.AddOrUpdate(EventTaskPriority.Migrations.All()); 
     context.TaskStatuses.AddOrUpdate(TaskStatus.Migrations.All()); 


     EventOrganiserTask.Migrations.All().Select(x => context.Entry(x.Priority).State == EntityState.Modified); 
     EventOrganiserTask.Migrations.All().Select(x => context.Entry(x.TaskStatus).State == EntityState.Modified); 

     context.Tasks.AddOrUpdate(EventOrganiserTask.Migrations.All()); 
    } 
} 

Следующие примеры экземпляров, которые я использую для данных.

Я создаю следующие методы для иностранных ключевых объектов

public static EventTaskType[] All() 
{ 
    return new[] 
    { 
     GetDeadline(), 
     GetEmail(), 
     GetTelephone(), 
     GetAppointment(), 
     GetSnailMail(), 
    }; 
} 
internal static EventTaskType GetDeadline() 
{ 
    return new EventTaskType("09974722-D03E-4CA3-BF3A-0AF7F6CA1B67", 1, "Deadline") 
    { 
     Icon = "" 
    } 
} 

Я называю следующие методы создавание основные данные.

public static EventOrganiserTask[] All() 
{ 
    return new EventOrganiserTask[] 
    { 
     GetBookHQ(1, new DateTime(Event.Migrations.EventDate.Year - 1, 10, 1)), 
     GetFindSponsor(2, new DateTime(Event.Migrations.EventDate.Year - 1, 10, 1)), 
     GetRegisterEvent(3, new DateTime(Event.Migrations.EventDate.Year - 1, 10, 1)), 
     GetBookFirstAid(4, Event.Migrations.EventDate.AddMonths(-6)) 
    }; 
} 

ПРИМЕЧАНИЕ: При создании основной записи, я вызываю метод в зарубежных ключевых классов, каждый раз - что является сутью проблемы, когда мне нужно поручить миграции отделяться этот пункт.

public static EventOrganiserTask GetRegisterEvent(int id, DateTime date) 
{ 
    return new EventOrganiserTask 
    { 
     id = id, 
     Title = "Register event", 
     Summary = "Register the road race with the region", 
     DueDate = date, 
     Priority = EventTaskPriority.Migrations.GetHighPriority(), 
     Person = Person.Migrations.GetRaceOrganiser(1), 
     TaskType = EventTaskType.Migrations.GetDefault(), 
     TaskStatus = TaskStatus.Migrations.GetDefault(), 
    }; 
} 

ПРИМЕЧАНИЕ. Когда я вношу изменения в данные приложения, внешние ключи не обновляются. Это должно быть связано и указывает, что мои объекты настроены неправильно.

Последняя:

Я все еще рву на себе волосы. Я исследовал это дальше и читал о том, что миграции были многопоточными (это был еще один поток в stackoverflow, но я не могу найти его снова). Действительно, я использую метод Seed, который, как я полагал, это то, что он говорит на жестяне, и является purley для посева данных, поэтому данные только добавляются (независимо от AddOrUpdate - что это все тогда). Итак, я посмотрел на поведение записей создается. Прежде всего я вызвал context.SaveChanges() после создания таблиц поиска. На этом этапе он не создает дубликатов, поскольку элементы ссылаются только один раз. Затем я разрешаю методу семян выполнять основные данные, но argggh - я вижу дубликаты (когда экземпляры вызываются по основным данным). Но это что-то значило в отношении порядка, в котором он создает записи.

Следующим шагом было создание двух миграций, но без каких-либо успехов.

Я надеюсь, что кто-то скоро подберет эту тему. Я вырываю волосы.

ответ

0

Хорошо, поэтому я наконец нашел свой ответ. Это было достаточно умно, чтобы создать отношения внешнего ключа от модели, но мне нужно было явно указать поле идентификатора внешнего ключа. Я выбрал API Fluent для явного задания отношений, и я установил значение поля id при отображении объекта.

modelBuilder.Entity<Task>() 
        .HasRequired(x => x.Priority) 
        .WithMany(x => x.Tasks) 
        .HasForeignKey(x => x.Priority_id); 

Здесь в методе семян

public class VeloPointDbConfiguration : DbMigrationsConfiguration<VeloPointDbContext> 
    { 
     public VeloPointDbConfiguration() 
     { 
      AutomaticMigrationsEnabled = true; 
      AutomaticMigrationDataLossAllowed = true; 
     } 

     protected override void Seed(VeloPointDbContext context) 
     { 

     context.TaskPriorities.AddOrUpdate(EventTaskPriority.Migrations.All());    

context.TaskStatuses.AddOrUpdate(TaskStatus.Migrations.All()); 
      EventOrganiserTask.Migrations.All().Select(x => context.Entry(x.Priority).State == EntityState.Modified); 
      EventOrganiserTask.Migrations.All().Select(x => context.Entry(x.TaskStatus).State == EntityState.Modified); 

      context.Tasks.AddOrUpdate(EventOrganiserTask.Migrations.All()); 
      // Foreign Key relationships 
      modelBuilder.Entity<EventOrganiserTask>() 
        .HasRequired(x => x.TaskStatus) 
        .WithMany(x => x.Tasks) 
        .HasForeignKey(x => x.TaskStatus_id); 
       modelBuilder.Entity<Task>() 
        .HasRequired(x => x.TaskType) 
        .WithMany(x => x.Tasks) 
        .HasForeignKey(x => x.TaskType_id); 
       modelBuilder.Entity<Task>() 
        .HasRequired(x => x.Priority) 
        .WithMany(x => x.Tasks) 
        .HasForeignKey(x => x.Priority_id); 

     } 
    } 
Смежные вопросы