我已经阅读了至少十几个其他问题,就像这个问题一样,但我很难理解其中的一些问题。
我习惯于使用存储库和链接到实体框架的代码优先实体来开发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操作上遇到了错误。
谢谢。
答案 0 :(得分:2)
看起来这是因为实体属于多个DataContexts。无论调用该操作的代码是什么,都应该使用相同的DataContext来创建实体,将其作为用于将其持久保存到数据存储区的实体。
在大多数情况下,您应该只保留一个DataContext实例。您可以使用像Castle这样的DI框架来定义/存储依赖项(在本例中为DataContext)作为Transient或PerWebRequest并将其注入服务和控制器,因此您将始终具有对DataContext的同一实例的引用。
答案 1 :(得分:2)
我是MVC&amp;的新手实体框架工作。经过多次战斗后,我遇到了同样的问题 这个解决方案对我有用。希望它对你们有用。
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读取整个对象并将其保存在当前上下文中,并且当您尝试修改实体状态时,它会告诉您已经有一个实体附加到当前上下文。只需调用保存更改就可以保存它。