如果我运行以下代码,则会抛出以下错误:
IEntityChangeTracker的多个实例
无法引用实体对象 public void Save(Category category)
{
using(var db = new NorthwindContext())
{
if(category.CategoryID == 0)
{
db.AddToCategorySet(category);
}
else
{
//category.RemoveTracker();
db.Attach(category);
}
db.SaveChanges();
}
}
原因当然是从我们从GetById方法获得的接口发送类别,该方法已经将EntityChangeTracker附加到类别对象。我还尝试将实体跟踪器设置为null,但它没有更新类别对象。
protected void Btn_Update_Category_Click(object sender, EventArgs e)
{
_categoryRepository = new CategoryRepository();
int categoryId = Int32.Parse(txtCategoryId.Text);
var category = _categoryRepository.GetById(categoryId);
category.CategoryName = txtUpdateCategoryName.Text;
_categoryRepository.Save(category);
}
答案 0 :(得分:0)
我自己还在学习实体框架,但也许我可以帮助一点。使用Entity Framework时,您需要了解如何处理不同的上下文。看起来您正试图通过以下方式尽可能地本地化您的上下文:
public void Save(Category category)
{
using (var db = new NorthwindContext())
{
...
}
}
...在您的数据访问方法中。你在GetById
方法中做了同样的事吗?如果是这样,你是否记得将你收回的物品分开,以便以后可以在不同的背景下附上?
public Category GetById(int categoryId)
{
using (var db = new NorthwindContext())
{
Category category = (from c in db.Category where Category.ID == categoryId select c).First();
db.Detach(category);
}
}
当你拨打Attach
时,它并没有试图踩到已经附加的上下文。这有帮助吗?
正如您在评论中指出的那样,当您尝试修改项目然后告诉数据库层保存它时会出现问题,因为一旦项目与其上下文分离,它就不再跟踪对它做出的改变。我可以通过几种方式来解决这个问题,但这些方法都不完美。
例如:
public void Save(Category category)
{
using (var db = new NorthwindContext())
{
db.Attach(category);
var stateEntry = db.ObjectStateManager.GetObjectStateEntry(category);
foreach (var propertyName in stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select(fm => fm.FieldType.Name)) {
stateEntry.SetModifiedProperty(propertyName);
}
db.SaveChanges();
}
}
这看起来有点丑陋,但整体上应该更具高效性和可维护性。另外,如果你愿意,你可以使它足够通用,可以在某个地方投入扩展方法,这样你就不必看到或重复丑陋的代码了,但你仍然可以从中获得它的功能。