已尝试附加或添加非新的实体,可能已从另一个DataContext加载

我遇到了NotSupportedException的问题,我得到:“尝试附加或添加一个非新的实体,可能是从另一个DataContext加载的。”

partial class SupplyOfert : Model { public SupplyOfert(int id = 0) { if (id > 0) this.get(id); } public Supplier supplier { get { return this.Supplier; } set { this.Supplier = db.Suppliers.SingleOrDefault(s => s.id == value.id); } } public override bool get(int id) { SupplyOfert so = (SupplyOfert)db.SupplyOferts.SingleOrDefault(s => s.id == id).Copy(this, "Supplies"); this._Supplies = so._Supplies; so._Supplies.Clear(); if (this.id > 0) { db.Dispose(); db = new Database(); db.SupplyOferts.Attach(this); // here I'm getting the exception return true; } else return false; } public override void save() { if (this.id  0) { db.SupplyOferts.DeleteOnSubmit(this); db.SubmitChanges(); } } } 

当我添加新记录时:

 SupplyOfert ofert = new SupplyOfert(); ofert.price = 100; ofert.publisher = "some publisher"; ofert.supplier = new Supplier(1); ofert.title = "some title"; ofert.year = DateTime.Today; ofert.save(); 

没关系,但是当我想更新记录时,使用:

 SupplyOfert ofert = new SupplyOfert(2); ofert.price = 220; ofert.publisher = "new publisher"; ofert.save(); 

我得到“NotSupportedExceptionw未处理”。

这是Model类:

 public abstract class Model { protected Database db = new Database(); public Model(){} ~Model() { db.Dispose(); } abstract public bool get(int id); abstract public void save(); abstract public void remove(); } 

这是复制方法:

 public static class ObjectProperties { public static object Copy(this object source, object destination, string skip = "") { if (source != null) { foreach (var sourceProperty in source.GetType().GetProperties()) { foreach (var destinationProperty in destination.GetType().GetProperties()) { if (destinationProperty.Name == sourceProperty.Name && destinationProperty.Name != skip) destinationProperty.GetSetMethod().Invoke(destination, new object[] { sourceProperty.GetGetMethod().Invoke(source, null) }); } } } else destination = null; return source; } } 

它只是数据库类:

 public class Database : DataClasses1DataContext 

我发现,这个问题与作业有关:

 this.supplier = so.supplier; 

但我不知道为什么……

这里的问题看起来像是在为每个实体创建一个单独的上下文(Model有一个db实例化的新副本)。 那么会发生什么:

  1. 您创建对象,并且它在其所附加的实体中具有上下文对象
  2. 使用它自己的上下文类创建一个新对象,并设置要更新的属性
  3. 它尝试保存并抛出一个exception,即该实体已经在另一个上下文中加载 – 创建它的那个上下文。

纠正此问题的第一步是不在实体内创建新的上下文。

我同意@Matthew

另外我想建议dbcontexts应该在一个使用块中:

 using(var db = new Database()) { // do something with db but not lazy loading } 

这对数据库上下文也是一个很好的读取