无需从数据库中获取子实体即可添加多对多关系

时间:2012-07-06 02:17:04

标签: asp.net-mvc asp.net-mvc-3 entity-framework entity-framework-4 many-to-many

我有Book和Author实体有很多关系,我试图用Database first方法保存关系(连接表中的记录)。

我想从我的代码工作版本

开始
 [HttpPost]
        public ActionResult Edit(BookViewModel bookv)
        {
            Mapper.CreateMap<AuthorViewModel, Author>();
            List<Author> authors = Mapper.Map<List<AuthorViewModel>, List<Author>>
(bookv.Authors.ToList());
//remove authors from book object to avoid multiple entities with same key error
           bookv.Authors.Clear();
            Mapper.CreateMap< BookViewModel,Book>();
            Book  book = Mapper.Map<BookViewModel,Book>(bookv);

            db.Books.Attach(book);          
            book.Authors.Clear();
            foreach (Author a in authors)
            {
                //Fetch Author and add relation to book object
                book.Authors.Add(db.Authors.Single(at=>at.AuthorId==a.AuthorId));
            }

            db.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
            db.SaveChanges();
            return RedirectToAction("Index");

        }

在上面的代码中,我从数据库中获取Author对象(record)以添加与book对象的关系。然而,我没有从数据库中获取Book对象,而是将其附加到上下文中。我不能用Author对象做类似的事情吗?

我尝试使用此代码执行此操作,但它首先将新记录添加到Author表并添加与book和新创建(不需要的)作者的关系:

 [HttpPost]
    public ActionResult Edit(BookViewModel bookv)
    {
        Mapper.CreateMap<AuthorViewModel, Author>();
        List<Author> authors = Mapper.Map<List<AuthorViewModel>, List<Author>>(bookv.Authors.ToList());
    //   bookv.Authors.Clear();
        Mapper.CreateMap< BookViewModel,Book>();
        Book  book = Mapper.Map<BookViewModel,Book>(bookv);

        foreach (Author a in book.Authors)
        {
            db.Authors.Attach(a);
        }

        db.Books.Attach(book);

        foreach (Author a in authors)
        {
            book.Authors.Add(a);
        }
     db.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
            db.SaveChanges();
            return RedirectToAction("Index");

        }

2 个答案:

答案 0 :(得分:2)

[HttpPost]
        public ActionResult Edit(BookViewModel bookv)
        {
            //create maps
            Mapper.CreateMap<AuthorViewModel, Author>();
            Mapper.CreateMap<BookViewModel, Book>();

            //convert view objects to model objects
            Book book = Mapper.Map<BookViewModel, Book>(bookv);
            List<Author> authors = Mapper.Map<List<AuthorViewModel>, List<Author>>   (bookv.Authors.ToList());

            book.Authors.Clear();
            db.Books.Attach(book);


            foreach (Author a in authors) { db.Authors.Attach(a); }

            book.Authors.Clear();

            foreach (Author a in authors) { book.Authors.Add(a); }

            db.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
            db.SaveChanges();
            return RedirectToAction("Index");

        }

答案 1 :(得分:1)

您是否尝试在db.Books.Attach(book)循环之前调用db.Authors.Attach(a)

另外,您是否尝试过将这本书添加给作者?比如a.Books.Add(book);而不是?

IOW,

db.Books.Attach(book);
foreach (Author a in book.Authors)
{
    db.Authors.Attach(a);
    a.Books.Add(book);
}