Attaching entities that contain other entities.
-
Hi, Is there any way to disable the recursive attaching that seems to occur in linq when I call the Attach method? Simple example: I have 2 entities. Customer and Order. Both are tables in the database. Each has a unique Id. Each order also has a CustomerId which is foreign key to the customer table. So this is a many to one relationship. Each customer can have many orders, but each order can only have 1 customer. Linq represents this as an EntitySet member in the customer class to hold all the orders and an EntityRef member in the Order class to hold the orders customer. Great. Works fine for loading. I've got deferred loading disabled (this is a disconnected app), and the load options set to load orders with customers. So I load the customer, and make some changes to it so need to save it. I only want to save the customer, none of the orders have changed. so I call myDataContext.Customers.Attach(myCustomer, true) Bang, error, "An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported." It all works fine if I remove the EntitySet member object. I'm assuming what's happening is the Attach method is attaching the customer and all it's orders, but I don't want this. I've tried manually attaching the orders as not modified: myDataContext.Orders.AttachAll(myCustomer.Orders, false) myDataContext.Customers.Attach(myCustomer, true) but I get the same error. Unless I remove the EntityRef from the order class. I'm assuming then that the problem is I can't attach either object first, because what ever I attach first contains a reference to the other one which hasn't been attached yet. Maybe I'm just totally confused. Any ideas?
Simon
-
Hi, Is there any way to disable the recursive attaching that seems to occur in linq when I call the Attach method? Simple example: I have 2 entities. Customer and Order. Both are tables in the database. Each has a unique Id. Each order also has a CustomerId which is foreign key to the customer table. So this is a many to one relationship. Each customer can have many orders, but each order can only have 1 customer. Linq represents this as an EntitySet member in the customer class to hold all the orders and an EntityRef member in the Order class to hold the orders customer. Great. Works fine for loading. I've got deferred loading disabled (this is a disconnected app), and the load options set to load orders with customers. So I load the customer, and make some changes to it so need to save it. I only want to save the customer, none of the orders have changed. so I call myDataContext.Customers.Attach(myCustomer, true) Bang, error, "An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported." It all works fine if I remove the EntitySet member object. I'm assuming what's happening is the Attach method is attaching the customer and all it's orders, but I don't want this. I've tried manually attaching the orders as not modified: myDataContext.Orders.AttachAll(myCustomer.Orders, false) myDataContext.Customers.Attach(myCustomer, true) but I get the same error. Unless I remove the EntityRef from the order class. I'm assuming then that the problem is I can't attach either object first, because what ever I attach first contains a reference to the other one which hasn't been attached yet. Maybe I'm just totally confused. Any ideas?
Simon
Never mind, I knocked up that simple example I described in the post, and things worked fine. I can't see what's different in my app, but it must be something, there's just too many entities and relationships to spot it obviously. I've tweaked things around a little bit and it works fine. Is there a pattern for how your supposed to work with Linq in a disconnected environment. I find myself loading huge entity trees even for simple things. E.g. If I load a customer, that loads all the orders, each order loads several items, each item loads it's stocking information and it's suppliers, each supplier loads...etc...All I really wanted was the customer. So what I end up with it lots of different methods to load different amounts of stuff. Like I have a LoadCustomer method, and a LoadCustomerWithOrders method and a LoadCustomerOrders method which takes a customer and loads the orders. I liked Linq to begin with but it's actually just starting to over complicate my data access layer. Are there any good sample apps out there that show nice clean patterns for this kind of thing. (I'll stop ranting now).. Thanks
Simon
-
Never mind, I knocked up that simple example I described in the post, and things worked fine. I can't see what's different in my app, but it must be something, there's just too many entities and relationships to spot it obviously. I've tweaked things around a little bit and it works fine. Is there a pattern for how your supposed to work with Linq in a disconnected environment. I find myself loading huge entity trees even for simple things. E.g. If I load a customer, that loads all the orders, each order loads several items, each item loads it's stocking information and it's suppliers, each supplier loads...etc...All I really wanted was the customer. So what I end up with it lots of different methods to load different amounts of stuff. Like I have a LoadCustomer method, and a LoadCustomerWithOrders method and a LoadCustomerOrders method which takes a customer and loads the orders. I liked Linq to begin with but it's actually just starting to over complicate my data access layer. Are there any good sample apps out there that show nice clean patterns for this kind of thing. (I'll stop ranting now).. Thanks
Simon
It really depends on the architecture you want to put together, but I would expect you to use lazy loading on this. Suppose, for instance, you have an Order class and each order has an associated set of products, I would load the order in, and when I need the products I would load them in.
Deja View - the feeling that you've seen this post before.
-
It really depends on the architecture you want to put together, but I would expect you to use lazy loading on this. Suppose, for instance, you have an Order class and each order has an associated set of products, I would load the order in, and when I need the products I would load them in.
Deja View - the feeling that you've seen this post before.
Yeah, this is what I've gone with. I only load the bits I need, but because I'm using classes created by the Linq designer thingy it means what I have is a Customer class with an Order member. So I load the Customer first, and any time I want to look at the customers order I have to check if the orders member is null, and if it is call a LoadCustomerOrders method to get the orders. I suppose it's no more complex than I would have done with a old style data access layer. I just don't like having a customer object and having to always be checking it's members for null as I don't know what's been loaded at this point. I feel like I'm constantly in danger of a NullReferenceException because I forget to check at one point before using it, but it doesn't show up for ages because it's only when you do things in a certain order. I suppose it just comes down to getting used to a slightly different pattern. I'm still not completely sold on Linq I don't think, I maybe need more time to get used to it. I'm actually most interested in trying it in a connected environment where you can just let Linq manage the deferred loading itself, and not worry about these things. Thanks Pete.
Simon
-
Yeah, this is what I've gone with. I only load the bits I need, but because I'm using classes created by the Linq designer thingy it means what I have is a Customer class with an Order member. So I load the Customer first, and any time I want to look at the customers order I have to check if the orders member is null, and if it is call a LoadCustomerOrders method to get the orders. I suppose it's no more complex than I would have done with a old style data access layer. I just don't like having a customer object and having to always be checking it's members for null as I don't know what's been loaded at this point. I feel like I'm constantly in danger of a NullReferenceException because I forget to check at one point before using it, but it doesn't show up for ages because it's only when you do things in a certain order. I suppose it just comes down to getting used to a slightly different pattern. I'm still not completely sold on Linq I don't think, I maybe need more time to get used to it. I'm actually most interested in trying it in a connected environment where you can just let Linq manage the deferred loading itself, and not worry about these things. Thanks Pete.
Simon
To be honest, I have a Business Layer and custom context wrapper that lets me load as and when I see fit, rather than having to let Linq control everything. It's based on the implementation of a BLL by Rick Strahl at west-wind.com. You may want to take a look at what he put together as a starting point.
Deja View - the feeling that you've seen this post before.
-
To be honest, I have a Business Layer and custom context wrapper that lets me load as and when I see fit, rather than having to let Linq control everything. It's based on the implementation of a BLL by Rick Strahl at west-wind.com. You may want to take a look at what he put together as a starting point.
Deja View - the feeling that you've seen this post before.
Cool, thanks. I've found it. I'll have a good look at that when I've got some free time.
Simon