0

I have a simple requirement (so I thought...!)

I have a model that consists of Order, OrderLine, Product.

I want to create an Order and add OrderLines (each OrderLine related to a Product). I create the Order and add new OrderLines to it. Between posts I store the Order entity in Session (or ViewState). Just so you know I have added suppport for binary serialisation which works fine.

The relationship is therefore Order > OrderLine(s) > Product(s).

You might have already guessed what the problem is - that when I SaveChanges() I get the usual 'AcceptChanges cannot continue because the object’s key values conflict with another object in the ObjectStateManager.' error.

I have referred to a number of articles online but none seem to handle this case (where I have the relationship across more than two entities) e.g. http://blogs.msdn.com/b/diego/archive/2010/10/06/self-tracking-entities-applychanges-and-duplicate-entities.aspx.

This must be a very common requirement surely? Is there anyone out there doing the same kind of thing with Entity Framework (and without using DTOs etc)?

Cheers - help! :)

Nick

Mark Chidlow
  • 1,432
  • 2
  • 24
  • 43
  • what do you mean "across multiple Posts"? is this a web application? if so, you don't need self tracking entities, and you shouldn't store it in session. you should respect the stateless nature of the web. STE is for multi-tiered applications (e.g WCF -> Silverlight, for example) – RPM1984 Dec 14 '10 at 10:24
  • Thanks. Well yes this is a web application and I do mean across page requests. I would like to use the EF generated Order entity to build the order (add order lines, notes etc). Why should I not? How else should I do this - by creating my own 'Order' entity (class), working with that, then copying across to a new EF Order Entity when saving?? Seems like a lot of extra work considering I have a ready-made class that understands the associations etc. What would you suggest in this instance? (I appreciate that the use of STEs may not be appropriate) – Mark Chidlow Dec 14 '10 at 10:31

2 Answers2

0

This is what I decided to do...

Use the EF generated entities and associations (NOT STEs - you are correct Nick) to build the order. Always include Foreign Keys.

Set MergeOption to NO TRACKING i.e. detached.

Save relevant Entities in SESSION between posts/page requests while the user builds the order.

Important: when associating child entities (e.g. OrderLines) do not associate existing child entities through relation but use the FK Id. So do not use OrderLine.Product = product, but use OrderLine.Product_Id = product.Id. This fixes issues where multiple entities exist from different contexts.

When the order is complete and ready to save, add to context and SaveChanges.

--

When EDITING existing order...

Set MergeOption to NO TRACKING.

Save relevant Entities in SESSION between posts/page requests while the user edits the order.

I use my own entity state indicator so that I can record whether an entity is added, modified or deleted when detached.

When the edits are complete and ready to save, attach to context, handle the changes (set ObjectState to MODIFIED etc) and SaveChanges.

--

Works a dream - short-lived context (UOW) - no View Model or DTO (simply use the Entity classes) - no complex code (detatching/attaching graphs etc).

Note: Does not store in VIEWSTATE. Need to look into this as I will want to change from InProc to SQL. Will update.

Maybe I've missed something but I have spent a LOT of time researching possible solutions for this.

Mark Chidlow
  • 1,432
  • 2
  • 24
  • 43
  • False alarm. Can store in ViewState OK (needed to use .Include when retrieving Order prior to edits and storing in ViewState). – Mark Chidlow Dec 15 '10 at 11:16
0

I hear this alot "NOT STEs" but why not? I have a multi-tiered app that has WinForms, WPF and ASP.Net components and am using my STEs for all layers. In ASP just make sure you persist your STE back to Viewstate\Sessionstate appropriately between posts/changes and your code should work fine.

I have entities that have many levels of relationships without issue, there are little examples of this because the principals are the same no matter how many levels. I recommend persisting with STEs if you have the time/patience to get your scripts right for your needs. I now have a solid framework based on STEs that I use in all my applications.

STE's allow me to access data in SharePoint (.Net 3.5) when the model and management app is actually .Net 4.0, this is one of the often overlooked benefits of STEs vs Entity Framework.

See Self-Tracking Entities: ApplyChanges and duplicate entities for help on your particular issue.