2

我已经阅读了至少十几个其他问题,就像这个问题一样,但我无法掌握其中的一些内容。

我习惯于使用链接到实体框架的存储库和代码优先实体来开发 ASP.NET MVC3。

我最近切换到具有服务开发的数据库优先 ADO.NET。我觉得这很干净,因为我可以通过我的外键访问东西。

无论如何,我的旧保存方法似乎被破坏了,因为我经常收到这个错误

一个实体对象不能被多个 IEntityChangeTracker 实例引用

所以这里看一下我的保存操作和我的服务:

行动:

[HttpPost]
        public ActionResult AddReview(Review review, int id)
        {
            User loggedInUser = userService.GetUserByusername(User.Identity.Name);
            review.WriterId = loggedInUser.UserId;
            review.ProductId = id;

            if (ModelState.IsValid)
            {
                reviewService.Save(review);
                Product product = productService.GetProduct(id);

                if(product.Quantity>=1)
                    product.Quantity--;
                product.TimesBought++;

                productService.UpdateRating(product, reviewService);

                loggedInUser.GoldCoins -= product.Price;
                Session["goldCoins"] = loggedInUser.GoldCoins;
                userService.Save(loggedInUser);
                productService.Save(product);

            }
            else
            {
                return View(review);
            }
            return RedirectToAction("Index", "Answers", new { reviewId = review.ReviewId });

服务:

public class ReviewService : Service<Review, CapstoneEntities>
    {

        ...

        public void Save(Review review)
        {


        using (var db = new CapstoneEntities())
        {
            if (review.ReviewId == 0)
            {
                db.Reviews.Add(review);
                db.Entry(review).State = EntityState.Added;
            }
            else
            {
                db.Entry(review).State = EntityState.Modified;
            }
            db.SaveChanges();
        }
    }
}

我怀疑这行代码:使用(var db = new CapstoneEntities()),但我不知道该怎么做。同样,这与我以前的做事方式完美配合,但现在我在几乎所有 CRUD 操作中都会遇到错误。

谢谢你。

4

2 回答 2

2

看起来这是由一个实体属于多个 DataContexts 引起的。无论调用该操作的代码都应该使用相同的 DataContext 来创建实体,因为它用于将实体持久保存到数据存储区。

在大多数情况下,您应该只保留一个 DataContext 实例。您可以使用像 Castle 这样的 DI 框架将依赖项(在本例中为 DataContext)定义/存储为 Transient 或 PerWebRequest,并将其注入到服务和控制器中,因此您将始终拥有对同一 DataContext 实例的引用。

于 2012-05-01T18:08:05.413 回答
2

我是 MVC 和实体框架的新手。经过很多努力后我遇到了同样的问题这个解决方案对我有用。希望它对你们有用。

var mediaItem = db.MediaItems.FirstOrDefault(x => x.Id == mediaItemViewModel.Id);
    mediaItem.Name = mediaItemViewModel.Name;
    mediaItem.Description = mediaItemViewModel.Description;
    mediaItem.ModifiedDate = DateTime.Now;
    mediaItem.FileName = mediaItem.FileName;
    mediaItem.Size = KBToMBConversion(mediaItemViewModel.Size);
    mediaItem.Type = mediaItem.Type;

//db.Entry(mediaItem).State = EntityState.Modified;// coment This line
db.SaveChanges();

因为您正在从 db 读取整个对象并将其保存在当前上下文中,当您尝试修改实体状态时,它会告诉您已经有一个实体附加到当前上下文。只需调用保存更改它就会保存它。

于 2014-12-16T11:04:51.147 回答