【问题标题】:Adding to many-to-many collection without querying the main entities添加到多对多集合而不查询主要实体
【发布时间】:2013-01-08 19:04:46
【问题描述】:

我有一个批处理,我需要在现有实体之间添加新关系,实体有大数据,我无法获取实体并添加它们,我试过这个:

  for .........
                Class Class = new Class() { ClassID = myClassId };
                context.AddToClasses(Class);
                Student std = new Student() { Id = myStdId };
                context.AddToStudents(std);
                context.ObjectStateManager.ChangeObjectState(Class, System.Data.EntityState.Unchanged);
                context.ObjectStateManager.ChangeObjectState(std, System.Data.EntityState.Unchanged);
                Class.ClassStudents.Add(std);

  .............

第一次调用会成功,但第二次调用会给我这个异常:

AcceptChanges 无法继续,因为对象的键值冲突 与 ObjectStateManager 中的另一个对象。确保密钥 在调用 AcceptChanges 之前值是唯一的。

试过了:

  for .........
                Class Class = new Class() { ClassID = myClassId };
                context.Attach(Class);
                Student std = new Student() { Id = myStdId };
                context.Attach(std);
                context.ObjectStateManager.ChangeObjectState(Class, System.Data.EntityState.Unchanged);
                context.ObjectStateManager.ChangeObjectState(std, System.Data.EntityState.Unchanged);
                Class.ClassStudents.Add(std);

  .............

例外:

EntityKey 值为空的对象不能附加到对象上 上下文。

我该怎么做?

【问题讨论】:

  • Class.ClassID 和 Student.Id 是主键属性吗?您究竟在哪一行得到第二个异常?

标签: c# .net sql-server visual-studio entity-framework


【解决方案1】:

如果 myClassId 和 myStdId 对可以重复并且在循环中没有特定顺序,您正在运行此代码,我将使用两个字典来保存已创建和附加的实体,以避免您创建和再次附加具有相同键的实体,如下所示:

var classDict = new Dictionary<int, Class>();
var studentDict = new Dictionary<int, Student>();

// for ... loop starts here

Class Class;
if (!classDict.TryGetValue(myClassId, out Class))
{
    Class Class = new Class() { ClassID = myClassId };
    context.Classes.Attach(Class);
    classDict.Add(myClassId, Class);
}

Student std;
if (!studentDict.TryGetValue(myStdId, out std))
{
    Student std = new Student() { Id = myStdId };
    context.Students.Attach(std);
    classDict.Add(myStdId, std);
}

Class.ClassStudents.Add(std);

// loop ends here

context.SaveChanges();

【讨论】:

  • 更新了我的问题,附件会给我一个问题!
  • 当您使用 .AddToXXX() 方法而不是 .Attach() 时,您的答案是最佳答案
猜你喜欢
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-11
  • 1970-01-01
相关资源
最近更新 更多