Asp.net mvc 实体框架不适当地将新记录插入导航表

Asp.net mvc 实体框架不适当地将新记录插入导航表,asp.net-mvc,sql-server-2008-r2,ef-code-first,entity-framework-6,Asp.net Mvc,Sql Server 2008 R2,Ef Code First,Entity Framework 6,我在插入具有多对多导航属性的记录时遇到问题 我有这些模型 //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; s

我在插入具有多对多导航属性的记录时遇到问题

我有这些模型

//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; }
}
Create
方法中,我使用ValueInjector将DTO映射到POCO

public void Create(BookDto bookDTO)
{
    Book book = new Book();
    book.InjectFrom<DeepCloneInjection>(bookDTO);
    bookRepository.Add(book);
    unitOfWork.Commit();
}
这会将数据适当地插入到
书籍
表和
书籍作者
表中,但会将新记录插入
作者
表中,即使我从控制器中传递了
作者
,其中包含
书籍作者


知道如何解决这个问题吗?

您缺少将现有作者附加到上下文的功能。你可以这样做:

public void创建(BookDto BookDto)
{
书=新书();
book.From(bookDTO);
foreach(书籍中的var作者。作者)
authorRepository.Attach(作者);
bookRepository.Add(book);
unitOfWork.Commit();
}
其中,泛型的
Attach
方法只是通过调用
dbset.Attach(实体)实现的。我假设所有存储库(
authorRepository
bookRepository
)共享相同的上下文实例。否则,上述方法将不起作用

数据库中已经存在
AuthorId
,这一事实并不重要。EF不会首先通过查询检查Id是否存在。如果对分离实体的对象图调用
Add
,它会尝试通过为父对象和所有子对象生成insert语句来插入整个图。通过附加子项,可以有效地关闭这些子项的INSERT语句

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