1

я столкнулся вопрос при вставке записей с многим ко многие свойства навигации,Entity рамка вставляет новую запись в таблицу навигации ненадо

У меня есть эти модели

//ModelBase 
public class ModelBase 
{ 
    [Key] 
    public long Id { get; set; } 
} 

//Book 
public class Book : ModelBase 
{ 
    public string Title { get; set; } 
    public virtual ICollection<Author> Authors { get; set; } 
    public virtual ICollection<PublishedBook> PublishedBooks { get; set; } 
} 

//Author 
public class Author : ModelBase 
{ 
    public string Name { get; set; } 
    public virtual ICollection<Book> Books { get; set; } 
} 

И DTOS называемых BookDto и AuthorDto для передача данных между слоями

С контроллера я заполняю данные в DTO и вызываю метод Create (который находится на отдельном уровне) для сохранения данных в базе данных,

BookDto bookDto = new BookDto() 
{ 
    Id = model.Id, 
    Title = model.Title, 
    Authors = model.AuthorIds.Select(c => new AuthorDto { Id = c }).ToList() 
} 

using (ServiceFactory facory = new ServiceFactory()) 
{ 
    factory.Book.Create(bookDto); 
} 

В методе Create я карта DTOs с POCO которые с помощью ValueInjector

public void Create(BookDto bookDTO) 
{ 
    Book book = new Book(); 
    book.InjectFrom<DeepCloneInjection>(bookDTO); 
    bookRepository.Add(book); 
    unitOfWork.Commit(); 
} 

И это вызывает Add метод в Genaric Repository базы

public virtual void Add(T entity) 
{ 
    dbset.Add(entity); 
} 

Это вставляет данные в Books таблицы и BookAuthors таблиц надлежащим образом, НО вставляет новую запись в таблицу Authors, даже если я передаю Authors, который имеет e xisting AuthorIds для Book.Authors с контроллера.

Любая идея, как исправить это?

ответ

2

Вам не хватает, чтобы приложить существующих авторов к контексту. Вы можете сделать это следующим образом:

public void Create(BookDto bookDTO) 
{ 
    Book book = new Book(); 
    book.InjectFrom<DeepCloneInjection>(bookDTO); 
    foreach (var author in book.Authors) 
     authorRepository.Attach(author); 
    bookRepository.Add(book); 
    unitOfWork.Commit(); 
} 

, где общие методы Attach просто реализуется вызовом dbset.Attach(entity);. Я предполагаю, что все репозитории (authorRepository и bookRepository) используют один и тот же экземпляр контекста. В противном случае вышеуказанное не будет работать.

Тот факт, что AuthorId уже существует в базе данных, не имеет значения. EF не проверяет, существует ли идентификатор сначала по запросу. Если вы назовете Add на графике объекта отдельных объектов, он попытается вставить весь граф, создав инструкции INSERT для родителя и для всех детей. Присоединив детей, вы фактически отключите инструкции INSERT для них.

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