【问题标题】:InsertOnSubmit doesn't attach?InsertOnSubmit 不附加?
【发布时间】:2010-03-03 22:24:11
【问题描述】:

创建新对象 (Foo) 后,我为 EntityRef 关联属性 (Bar) 设置键 (BarId)。然后我想将新对象插入到数据库中,然后能够访问延迟加载的子对象。

不幸的是,延迟加载属性在调用 InsertOnSubmit() 后返回 null。但是,如果我将对象 Attach() 到数据上下文,它会返回正确的对象。

以下代码成功地将我的新对象插入数据库,但没有正确设置子 Bar 属性的延迟加载:

var foo = new Foo();
foo.BarId = 123;
context.GetTable<Foo> ().InsertOnSubmit( foo );
foo.Bar.Something();    // throws NullReferenceException

此处,Bar 对象已正确加载:

var foo = new Foo();
foo.BarId = 123;
context.GetTable<Foo> ().Attach( foo );
foo.Bar.Something();    // method is called on lazy-loaded Bar object

在 InsertOnSubmit 之前调用 Attach 会导致后者抛出“无法添加已存在的实体”异常。

那么,这是 LINQ-to-SQL 中的错误,其中插入的对象未正确附加到数据上下文?

我该如何解决这个问题?

【问题讨论】:

  • 使用 InsertOnSubmit 时,需要 SaveChanges 将新对象提交到数据存储区。这可能是问题所在,因为创建一个新数据项并不会先天地将数据上下文关联到它(延迟加载),直到对象被上下文填充(我认为)。
  • 我明白了。不幸的是,我在数据上下文之上构建了一个安全层,在调用 SubmitChanges() 之前检查对象/用户权限。该代码需要访问我的对象的某些属性,包括延迟加载的对象。这是否是一个好主意值得怀疑,但这是我现在必须使用的。
  • @NickLarsen:我刚刚测试了这个,你是对的。调用 SubmitChanges() 后延迟加载工作。

标签: c# linq-to-sql


【解决方案1】:

我会设置 Bar 属性而不是 Foo 类的 BarId 属性。在我看来,Linq-to-sql 在这里做错的是首先拥有 BarId 属性。它没有增加任何价值,并且违背了 OOP 的核心原则。所以,我会把你的代码改成这样:

var foo = new Foo();
foo.Bar = //get bar with id: 123;
context.GetTable<Foo> ().InsertOnSubmit(foo);
foo.Bar.Something();

【讨论】:

  • 这是有道理的。唯一的缺点是现在我需要通过显式查询 Bar 来为我的代码添加少量额外的复杂性,而不仅仅是设置一个 ID。
  • 是的,但在我看来它好多了。从 OO 的角度来看,它看起来好多了。看看其他的 ORM,比如 EF 或 nhibernate。
猜你喜欢
  • 2011-01-27
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多