268
Vote

Provide better support for working with disconnected entities

description

This item is to track adding better support for change tracking with graphs of disconnected entities. For more information see this discussion:

"Merge Disconnected Object Graph"
http://entityframework.codeplex.com/discussions/432661

And this user voice item:

"Merge method: automatic synchronization of relationships on a disconnected entity"
http://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/1069431-merge-method-automatic-synchronization-of-relation

comments

RoMiller wrote Feb 14, 2013 at 10:15 PM

EF Team Triage: We agree that this would be a good scenario to enable. Taking into account where we are in the EF6 release along with the size and the impact of this feature our team is not planning to implement it in EF6. Therefore, we are moving it to the Future release to reconsider in the next release.

bojanv55 wrote Jun 11, 2013 at 9:04 AM

GraphDiff solves the problem to some extent, but it would be much better if we could have the same syntax as in NHiberate (to call on object Graph with just method .Merge() - and every relation should be derived from existing configuration or convention).

weitzhandler wrote Jul 1, 2013 at 1:31 AM

I never knew NHibernate offers that!
I should really start adopting NHibernate for my next upcoming project. I'm now facing serious issues having to update all the descendants manually. Enormous pain.

JENSC wrote Jul 4, 2013 at 10:28 AM

I can't believe that there are only 43 votes for this,
as nearly every MS based web developer should have this requirement.
At least if you create a professional, layered architecture with persistance
ignorance etc.
I would see merging as a key feature of an ORM in conjunction with the standard responsibilities
(mapping, querying/loading, state management, data manipulation, transaction handling,..).

Merging and transition between layers is a time consuming part of each software development
but should at 95% be done automatically based on conventions with just a small share of
indivual scenario specific operations.

lennart77 wrote Jul 8, 2013 at 12:58 PM

I am also kind of baffled that EF doesn't provide support for this. It is such a common problem in all but the simplest designs with the simplest data models.

We have been looking at GraphDiff but it is still young, has some bugs and the developer currently lacks time to maintain it. GraphDiff looks very promising though, so if someone had the time to aid in its development (I don't regretfully) it could very well prove an adequate solution to the problem until its included in standard EF.

weitzhandler wrote Jul 8, 2013 at 2:54 PM

I that for the future of EF, I'd like to see an implementation of GraphDiff in both styles, Fluent API (as GraphDiff is currently implemented), and via attributes (as in NHibernate). That would be just awesome.

While exploring more about NH I'm finding out that it offers more features the EF. I'll consider using it for our next upcoming projects.
EF made a great move when making it open-source, things are obviously moving faster this way.

erictosi wrote Jul 11, 2013 at 4:18 PM

Only 54 votes ?

How do you manage your entities in complex domain with bounded contexts ?

The simple case of reference data in comboBox coming from a referential context and assigned to a BusinessContext via a navigation property is not so trivial.

ForeignKeys simplify things, but if we link an object graph it's horrible !
And "sometimes" we need entire graph and prefer delegate the loading of all detached element in another context.

ie : City/Country/CountryStates/JetLag preloaded vs a CityID

A simple service can load the complete City Graph and attach It in another context, becsause locally I need business rules with JetLag.

magnusrodrigo wrote Aug 30, 2013 at 2:24 PM

I think this is an essential feature that any developer that works with N-Layer architecture needs. Only 69 votes, this is sad.

mickey_puri wrote Oct 2, 2013 at 2:19 PM

This is such a basic requirement that the failure to deal with it feels more like an omission / bug.

This "feature request" should be re-classified as a "bug-fix" and prioritized accordingly - with a point release to plug the gap.

ltctech wrote Oct 3, 2013 at 12:25 AM

The lack of proper support for disconnected graphs in EF is a big headache. I was working on a web form with a backing entity composed of five or so tables with FK relationships to other tables based on drop down selections. When I attempted to update the entity navigation properties on the way back I had tons of relationship exceptions once attached.

Eventually I gave up and wrote an extension method that copies the scalar values of a given entity and attached it to a context with a given state. Then modified all of my code first entities navigation properties to update the associated scalar when set. Then I go through each child in the entity and attach to context using this extension method. It's a very nasty hack but it works for what I am doing with it.

jperciot wrote Oct 4, 2013 at 8:08 AM

I agree with both of these people, it's a functionaly that is crucial for developers.

I can't stand it was not added since the first release of such a great framework.

Thank you for doing the best for us !

happynomad wrote Nov 18, 2013 at 4:09 AM

I think another approach is better than the one here. Instead of sending the entire modified object graph over the wire, why not instead just send the delta? You wouldn't even need generated DTO classes in that case. If you have an opinion about this either way, please let's discuss is at http://stackoverflow.com/questions/1344066/calculate-object-delta .

Mady007 wrote Nov 20, 2013 at 3:07 PM

I have a scenario where a complex graph is sent over to server to merge with database. First step is compare persistent graph and transient graph then
  1. Add entities from transient graph which are missing in persistent graph.
  2. Update entities from transient graph which are matching in persistent graph.
  3. Delete entities from persistent graph which are not found in transient graph.
    This is the obvious case and valid steps if the transient graph is generated from the database though it is disconnected. I do not want you to confuse with concurrency lets keep it simple.
The step 3 is not valid if the transient graph is not generated from database rather it is build from various sources and sent over to server to merge with database. In this scenario, if you analyze step 3 If an entity in a collection is not present in the transient graph which may be existing on the persistent graph will be deleted.
I found Graphdiff can address this issue with a small change. The following link may not sound good presentation of the issue but it gives you the general Idea
http://stackoverflow.com/questions/20009938/disconnected-complex-graph-with-disconnected-child-entities/20076255?noredirect=1#comment29945806_20076255

canotony wrote Dec 11, 2013 at 6:19 PM

Agreed, this should have way more votes.

As many before already established this is a very common scenario for anybody working in an NTier app. Currently we are "manually" building the object graph (for persistence) using the navigation properties in the POCO entities

Hopefully the low number of votes will not be a factor in giving this feature a higher priority . This will greatly enhance the capabilities of what is already a very good framework.

thanks

programad wrote Jan 16 at 9:14 AM

I wrote a very poor implementation for "merge". Any additions are welcome.
foreach (var property in typeof(T).GetProperties())
                    {
                        var subEntity = property.GetValue(entity);
                        if (subEntity != null)
                        {
                            var subEntityType = subEntity.GetType();

                            if (!subEntityType.Namespace.Equals("System") && !subEntityType.Namespace.Equals("System.Collections.Generic") && !subEntityType.IsEnum)
                            {
                                var subDbSet = db.Set(subEntityType);
                                subDbSets.Add(subEntityType, subDbSet);

                                bool isNewEntity = false;
                                var compositeKey = db.KeysFor(subEntityType);
                                object[] actualKey = new object[compositeKey.Count()];

                                for (int i = 0; i < compositeKey.Count(); i++)
                                {
                                    var primaryKeyProperty = subEntityType.GetProperty(compositeKey.ElementAt(i));
                                    var primaryKeyValue = primaryKeyProperty.GetValue(subEntity);

                                    actualKey[i] = primaryKeyValue;

                                    if (primaryKeyProperty.PropertyType == typeof(int))
                                        if ((int)primaryKeyValue == 0)
                                            isNewEntity = true;
                                }

                                if (isNewEntity)
                                    subDbSet.Add(subEntity);
                                else
                                {
                                    var obj = subDbSet.Find(actualKey);
                                    if (obj != null)
                                        property.SetValue(entity, obj);
                                }
                            }
                        }
                    }

Inglor wrote Jan 28 at 2:06 PM

This has my vote.

Inglor wrote Jan 30 at 10:40 PM

I felt I should add a better comment to this. I have been using EF since 4.0. Where the promise of disconnected POCO's in N-Tier started. We are now on version 6.0.2 and still no support for state management with disconnected entities. I have recently started a new project and decided to use EF 6. Please put this in the next release. I like entity framework, I have put a large amount time into learning it. I don't want to have to drop it in favour of n-Hibernate.

shkup wrote Feb 6 at 7:05 PM

If I would know that this will be the situation when I started my last project I wouldn't adopt it.
When you use the context in the server to load data and change it on the client (common scenario I would say) you have to write a lot of code at the server to find out what data have changed.
Not to mention that you should reload the original entity from the db for comparison purposes.
I have tried GraphDiff but it has bugs and you risk data corruption.
VERY DISSAOPINTING!

bjlewies wrote Mar 2 at 2:51 PM

This is, in my humble opinion, not a nice-to-have but an absolute must-have! I have to admit that I was caught unaware by this problem and as a result the delivery of one of my projects has been affected.

Were it not for the investment we have already made in terms of skills development and adoption of the technology, I would have summarily dropped Entity Framework altogether. I will be monitoring this issue closely - if this does not get fixed soon I will have no choice but to abandon EF and go with NHibernate.

I agree with the previous comments that this is basic functionality. I think the number of people who have voted on this issue does not reflect the severity and impact of the problem - people don't bother to investigate and report the problem... they merely give up and switch to "easier" alternatives like NHibernate.

granadaCoder wrote Apr 22 at 8:37 PM

I showed a Java guy (who uses Hibernate) my EF code for disconnected-graphs and handling all the Adding, Updating, and Deleting.

He said "It makes my eyes hurt".

I wrote the same code in NHibernate, and wow.

When I bring this up to people who are familiar with NHibernate, and they are like "EF doesn't have .Merge??? DEAL-BREAKER".

I have to agree. Manually mapping every object-graph, every-time.......wow.

4n41yz3r wrote May 5 at 4:02 PM

This thing would have saved me tons of unnecessary boilerplate code. Please, consider adding it.

jmoisespg wrote May 19 at 8:07 PM

I work in a large company with tons of developers, I like EF, but nobody here likes it just because it misses the "Merge" feature.
I think it's not a "MUST HAVE", it's like symbiotic of any ORM...
All of my coleagues have dropped EF6, and I'll be doing that soon if I don't see this feature set on next releases.
Besides it's so basic.

etosi wrote May 23 at 10:21 AM

Is this planned in EF 7 ?
Or we must go definitiveley to NHibernate...

ajcvickers wrote May 23 at 2:15 PM

@etosi and others: better support for disconnected entities is a key part of the plan for EF7, although we don't have specific details written down yet.

taraman wrote May 23 at 7:25 PM

do you have any due date to implement this very critical feature in EF 7
in my current project I am using GraphDiff, but in the next project I need to determine if I will continue with EF or go with NHibernate (which didn't work with it before)

so it will be a trade off between learning curve (Hibernate) versus write a mass code to handle related objects tracing

thanks
Mohamed Taraman

bhall wrote Jun 11 at 7:28 PM

Yeah this is why I have not used EF since it came out. It does not feel like a full ORM because of this. Every once in a while, I check to see if it has been added. It should be a warning when people find mapping a class to itself useful.

rajithakba wrote Jun 17 at 12:30 PM

Finally the wisdom almost - was extremely happy seeing this item in flight. Literally spent couple of days to understand the problem and possible solution.
Hope the team will include this feature in an upcoming release.

jimmymain wrote Today at 5:22 AM

I note that entity framework 7 is in the early stages of development.
please include the top voted feature into this next major release...