2016-08-07 2 views
0

Я использую Entity Framework (6.1.3) с первым подходом кода. У меня есть модель класса кино и модель класса тег, который выглядит следующим образом:От многих до многих отношений - Entity Framework создает новые объекты

public class Movie 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<Tag> Tags { get; set; } 
} 

public class Tag 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

В DbContext я перезапись метод OnModelCreating для настройки отношения один-ко-многим так:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Movie>() 
       .HasMany(a => a.Tags) 
       .WithMany() 
       .Map(x => 
       { 
        x.MapLeftKey("Movie_Id"); 
        x.MapRightKey("Tag_Id"); 
        x.ToTable("MovieTags"); 
       }); 

    base.OnModelCreating(modelBuilder); 
} 

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

Например, у меня уже есть два тега «Foo» (Id: 1) и «Bar» (Id: 2) в базе данных. Теперь я создаю новый объект Movie и вставляю существующий тег «Foo» (загруженный из базы данных) и новый тег «Foobar» в коллекцию объекта. После добавления этого фильма в DbContext и вызова метода SaveChanges в моей базе данных есть два новых тега.

Почему платформа Entity Framework вставляет существующий тег в мою базу данных? Что мне нужно изменить, чтобы вставить только отсутствующий тег?

Edit-1: Вот код контроллера, где я добавить теги и сохранить его

List<Tag> tagList = new List<Tag>(); 
// ViewModel.Tags either contains the Tag-Id or the Tag-Name (if it is new) 
foreach (string tag in viewModel.Tags) 
{ 
    if (IsDigitsOnly(tag)) 
    { 
     // Load the existing Tag from the DbContext and add to List 
     tagList.Add(TagService.Get(int.Parse(tag))); 
    } 
    else 
    { 
     // Create new Tag 
     tagList.Add(new Tag() { Name = tag }); 
    } 
} 

Movie movie = new Movie(); 
movie.Name = viewModel.Name; 
movie.Tags = tagList; 

MovieService.Insert(movie); 

Вот MovieService код с вставкой

public void Insert(Movie movie) 
{ 
    Context.Movie.Add(movie); 
    Context.SaveChanges(); 
} 

Edit-2 : Я нашел проблему! Это была проблема с тем, как я создал свой проект. Я использовал Ninject для DI, и я не связывал DbContext с запросом (InRequestScope). Поэтому каждый раз, когда один из моих сервисов назывался, он использовал другой DbContext, и из-за этого он не знал уже загруженных тегов.

+0

Не могли бы вы исправить заголовок сообщения - что вы принимаете во многих отношениях. –

+0

Да, я изменил его. Я не знаю, почему я написал «один для многих». Я знаю, что это много для многих ... – Shamshiel

ответ

0

Не могли бы вы предоставить код, в котором вы добавляете тег?

В то же время, я предполагаю, что это что-то вроде

Movie.Tags.Add(new Tag { Name = "foo" }); 

Вы, вероятно, хотите добавить существующий тег следующим образом:

Movie.Tags.Add(ctx.Tags.First(T => T.Name == "foo")); 

... или эквивалентный код, который получит тег из вашего контекста.

Кроме того, вы можете сделать так, чтобы метки ICollection были виртуальными, чтобы прокси-сервер мог его переопределить. Это может быть трудно найти источник ошибок.

+0

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

+0

Отлично. Удачи. – DPH

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