C# “理解例外情况”;一个实体对象不能被IEntityChangeTracker的多个实例引用。”;
我正在做一个项目,我应该做一个电子书商店。这是一个实体关系模型,我使用它在SQLServer中生成了一个DB 现在,在使用以下代码生成账单时,我得到了一个C# “理解例外情况”;一个实体对象不能被IEntityChangeTracker的多个实例引用。”;,c#,linq,entity-framework,exception,C#,Linq,Entity Framework,Exception,我正在做一个项目,我应该做一个电子书商店。这是一个实体关系模型,我使用它在SQLServer中生成了一个DB 现在,在使用以下代码生成账单时,我得到了一个实体对象不能被多个EntityChangeTracker实例引用。调用实体关系模型的SaveChanges()方法时出现异常(ebs) 这是代码。 我正在会话中维护购物车。此外,用户id也保留在会话中 List<Title> cartItems = (List<Title>)Session["eStoreCart"];
实体对象不能被多个EntityChangeTracker实例引用。
调用实体关系模型的SaveChanges()方法时出现异常(ebs
)
这是代码。
我正在会话中维护购物车。此外,用户id也保留在会话中
List<Title> cartItems = (List<Title>)Session["eStoreCart"];
int userid = Int32.Parse(Session["eStoreUserId"].ToString());
User us = ebs.Users.SingleOrDefault(u => u.UserId == userid);
Bill bl = new Bill();
bl.BillAmount = Decimal.Parse(lblBill.Text);
bl.BillDate = DateTime.Now;
foreach (Title item in cartItems)
{
bl.Titles.Add(item);
}
us.Bills.Add(bl);
ebs.SaveChanges();
Response.Redirect("Orders.aspx");
List cartItems=(List)会话[“eStoreCart”];
int userid=Int32.Parse(会话[“eStoreUserId”].ToString());
User us=ebs.Users.SingleOrDefault(u=>u.UserId==UserId);
账单bl=新账单();
bl.billmount=Decimal.Parse(lblBill.Text);
bl.BillDate=DateTime.Now;
foreach(cartItems中的标题项)
{
bl.标题。添加(项目);
}
美国法案新增(bl);
ebs.SaveChanges();
响应重定向(“Orders.aspx”);
我对实体框架和LINQ完全陌生。因此,如果您有任何帮助来解释发生了什么,我们将不胜感激。看起来您可能正在创建
DbContext-ebs
作为实例变量并保留它。相反,你应该考虑你的实体上下文轻量级并按需创建它们,即每次需要查询或修改数据存储时,尤其是因为在Web应用程序中使用这个数据。
请查看这些文档:和
具体而言,请注意:
使用Web应用程序时,请根据使用上下文实例
请求
因此,不要保持长时间运行的DbContext
:当您想要修改数据存储时,使用块在中创建一个新的DbContext
非常轻量级,因此您可以按需构建它们并将其拆下
另见
现在,至于例外情况:我认为这是由于会话中存储的标题
对象造成的:这些对象必须是在另一个DbContext
中创建的。您可以尝试将它们附加到新的DbContext
(查看上面链接的文档)。但另一种方法是:不要在会话中保留标题
对象,而是保留这些对象的ID,然后在新的DbContext
中再次查找它们
大概是这样的:
List<int> cartItemIds = (List<int>)Session["eStoreCart"];
int userid = Int32.Parse(Session["eStoreUserId"].ToString());
using (var ebs = new MyDbContext())
{
User us = ebs.Users.SingleOrDefault(u => u.UserId == userid);
Title title = null;
Bill bl = new Bill();
bl.BillAmount = Decimal.Parse(lblBill.Text);
bl.BillDate = DateTime.Now;
foreach (var id in cartItems)
{
title = ebs.Titles.Where(t => t.Id == id);
bl.Titles.Add(title);
}
us.Bills.Add(bl);
ebs.SaveChanges();
}
Response.Redirect("Orders.aspx");
在您的情况下,代码可能如下所示:
List<int> cartItemIds = (List<int>)Session["eStoreCart"];
int userid = Int32.Parse(Session["eStoreUserId"].ToString());
using (var ebs = new MyDbContext())
{
User us = ebs.Users.SingleOrDefault(u => u.UserId == userid);
Title title = null;
Bill bl = new Bill();
bl.BillAmount = Decimal.Parse(lblBill.Text);
bl.BillDate = DateTime.Now;
foreach (var id in cartItems)
{
title = ebs.Titles.Where(t => t.Id == id);
bl.Titles.Add(title);
}
us.Bills.Add(bl);
ebs.SaveChanges();
}
Response.Redirect("Orders.aspx");
List cartItemIds=(List)会话[“eStoreCart”];
int userid=Int32.Parse(会话[“eStoreUserId”].ToString());
使用(var ebs=new MyDbContext())
{
User us=ebs.Users.SingleOrDefault(u=>u.UserId==UserId);
Title=null;
账单bl=新账单();
bl.billmount=Decimal.Parse(lblBill.Text);
bl.BillDate=DateTime.Now;
foreach(cartItems中的变量id)
{
title=ebs.Titles.Where(t=>t.Id==Id);
bl.标题。添加(标题);
}
美国法案新增(bl);
ebs.SaveChanges();
}
响应重定向(“Orders.aspx”);
另一个提示:查看ASP成员API以获得一些额外的webapp用户支持。您可能不需要做太多更改,您将获得一些API来执行密码策略/过期/更改等操作。您是否在使用块中访问ebs
,例如:使用(var ebs=new myenties()){…}
?不,我不是。这是单个按钮控件下的代码。我使用了这段代码,唯一的更改是“使用(ebookstoredmodelcontainer ebs=new ebookstoredmodelcontainer()”,这实际上在ebs.SaveChanges()中给出了相同的错误代码>行。兰根:你还有其他的上下文保持开放吗?我想是的。我有一个全局声明的ebookstoredmodel ebs
,在页面加载
,我有ebs=new ebookstoredmodel
。我只在整个页面中使用了这个,它在所有页面中都正常工作,除了这个。谢谢你的帮助。我不得不做一些手脚,这段代码可以正常工作foreach(cartItems中的Title项){bl.Titles.Add(ebs.Titles.SingleOrDefault(ttl=>ttl.TitleId==item.TitleId));}`