tags:

views:

164

answers:

1

After creating a new object (Foo), I set the key (BarId) for an EntityRef association property (Bar). I then want to insert the new object into the database, and be able to access the lazy-loaded child object afterward.

Unfortunately, the lazy-loading property returns null after the call to InsertOnSubmit(). It returns the correct object if I instead Attach() the object to the data context, however.

Here's code that successfully inserts my new object into the database, but doesn't correctly setup lazy-loading for the child Bar property:

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

Here, the Bar object is properly loaded:

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

Calling Attach before InsertOnSubmit causes the latter to throw a "Cannot add an entity that already exists" exception.

So, is this a bug in LINQ-to-SQL, where inserted objects are not properly attached to the data context?

How do I fix this?

A: 

I would set the Bar property instead of the BarId property of your Foo class. In my opinion what Linq-to-sql does wrong here is to have the BarId property in the first place. It doesn't add any value and It goes against core principals of OOP. So, I would change your code to something like this:

var foo = new Foo();
foo.Bar = //get bar with id: 123;
context.GetTable<Foo> ().InsertOnSubmit(foo);
foo.Bar.Something();
Mattias Jakobsson
That makes sense. The only downside is now I need to add a small amount of extra complexity to my code by explicitly querying for Bar, rather than just setting an ID.
MikeWyatt
Yes, but in my opinion its a lot better. It looks a lot better from a OO perspective. Just look at other ORM's like EF or nhibernate.
Mattias Jakobsson