1

我有一个无法找到解决方案并需要一些帮助的场景我该如何实现这一点,我想为客户获取当前记录修改它而不是更新我想将新记录添加到表中获取历史变化信息

    client c = new client();
    using (DBEntities db = new DBEntities())
    {
        // get current records in the client table for client
        IQueryable<client> co = from p in db.client where p.CUS_NUMBER == scd.cus_number && p.isCurrent == true select p;

        c = co.First();

        //update email and and address
        c.EMAIL = Helper.CleanInput("mymail@mm.com");
        c.ADDRESS = Helper.CleanInput("123 Sheppard");

        //instead of updating current record I'd like to add new record to the table to keep historical changes
        db.AddToclient(c);
        db.SaveChanges();
        //I get error that 
        //An object with the same key already exists in the ObjectStateManager. 
        //The existing object is in the Modified state. An object can only be added to 
        //the ObjectStateManager again if it is in the added state.

完全错误

ObjectStateManager 中已存在具有相同键的对象。现有对象处于已修改状态。只有处于添加状态的对象才能再次添加到 ObjectStateManager。

4

4 回答 4

1

删除此代码 db.AddToclient(c);,其余一切都很好,您已经通过其引用访问该对象,因此无需再次添加它。当您调用时它会被修改savechanges()

或者如果要添加新对象,请使用克隆c = co.First().Clone();

于 2013-02-26T10:33:15.977 回答
0

看起来您正在向数据库添加同一行,并且由于再次添加具有相同主键的同一行而出现错误,而数据库不允许这样做。

尝试添加新行并创建另一个表,该表保留旧行的历史信息和引用作为外键。您可以添加一个布尔字段来保存有关删除的信息,让 It isDeleted。

希望它会有所帮助谢谢

于 2013-02-26T10:45:10.197 回答
0

给出错误的原因db.AddToclient(c);是因为该对象正在被对象上下文跟踪,可能在数据库中。

完成您正在尝试做的事情的最佳方法是如下所示:

var newClient = new client()
{
    EMAIL = Helper.CleanInput("mymail@mm.com"),
    ADDRESS = Helper.CleanInput("123 Sheppard"),
};

db.AddToclient(newClient);
db.SaveChanges();
于 2013-02-26T10:35:53.063 回答
0

在 Entity Framework 中,默认情况下从数据库中检索到的所有对象都由 ObjectContext 实例跟踪。Entity Framework 在内部映射了他的 Key 跟踪的所有对象。这种模式称为身份映射。这意味着每个键只有一个实体实例。因此,您不需要再次调用 Add,因为实体已经在 EF 地图上。你只需要调用 SaveChanges 来保存修改过的实体。

在您的情况下,您是:

1 - 创建 EF ObjectContext 的新实例;
2 - 在您的 LINQ 查询中检索实体;
3 - 更改检索到的实体的属性值;
4 - 再次添加到 ObjContext;//错误!
5 - 调用 SaveChanges()

第 4 步不是必需的,因为 ObjectContext 已经知道检索到的对象。

于 2013-02-26T10:58:05.843 回答