Closed JamezG12 closed 1 year ago
@JamezG12 EF determines the order of operations for SaveChanges based on dependencies between different entity types. The order in which entities are added with DbContext.Add or DbSet.Add is not preserved, neither is the order of entities in navigation properties. Even if EF did preserve the order on insertion, most database engines don't guarantee to preserve the order on query (even though it may appear that way for simple cases) so it usually wouldn't help to have ordered inserts anyway. That being said, issue #9067 is tracking support for this through mapping for navigation properties.
Could you provide some more details as to why you need the order to be preserved?
Hi @ajcvickers, thanks for getting back to me.
I appreciate EF doesn't preserve the order of insertion to a DB with relation to multiple types of entities, as it needs to insert based on it's mappings, but we have the parent record already and we're just inserting new child records.
We had a set of documents that need to be in a specific order, we assumed that if we add these to an entity's collection and SaveChanges is called, they'd be inserted in the same order to the database.
Not necessarily with sequential ID's, but at least in the order they were in when they were in memory.
I found it quite strange that EF was generating a query where it appears that it's trying to preserve the order of insertion using _Position, it just looks like it's putting the parameter values in the wrong order.
The test case we wrote looked like EF was consistent in the order it inserted the records, 1,18,17,15,14.
I'm quite happy to accept that EF doesn't support ordering of inserts, it just doesn't seem intuitive that you'd add to your ORM entity in one way, for the framework to completely ignore the order in which your entities were in memory.
Does this mean that every entity we have that needs to be ordered a specific way, must have something like an Order or Sequence number, rather than relying on the Identity field and the order they were added to the collection?
Cheers,
James
@JamezG12 Yes.
Fantastic, thanks very much for your time that'll sort our issues and helps fill gaps in my knowledge.
Cheers,
James
This is completely unacceptable! The ORM's purpose is to bridge the gap between Object Model and persistence, which this particular ORM is not making possible!!! We only "thing" we have to accept is having to have a primary key property (that makes no sense to the Object Model) but, sure, we accept this as a requirement in relation to the SQL-based storage media.
DO NOT use the storage engines as an excuse. MOST of the the database management systems will use the next consecutive number (SERIAL, or IDENTITY) for the consecutive inserts and primary keys being of integer type. We don't care how the rows will be physically stored on disk (and that's not what you should be bringing this up here).
Tell us straight - you are using optimizations to kick the EF6 out of the ball park, we get it, again. BUT then it's not an Object Relational Mapper. Imagine BMW telling me that to produce the fastest vehicle they need to put the engine right smack in the middle of the car and put passengers in the trunk. That's basically what you are proposing!
Let the database decide how it would Store the rows, and US how we populate dependent navigational collections: a) we create an entity A with a dependent collection of B, 2) the B object has to be in the order the B have been imported from a text file, 3) Now we have to add a new property to B for sorting that make NO SENSE to the object model, 4) why don't we just switch to ADO.NET????
Or how about this: you give us a DbContext.Database property that controls whether the INSERT order shouldn't be preserved for HIGH THROUGHPUT day trading scenarios.
We encountered an ordering issue when we were inserting multiple records to the database.
We expected the order of the child entities to be preserved when we called SaveChangesAsync(). SaveChanges() did not make a difference either.
The inconsistent insert order only seemed to happen consistently when we inserted 20 child items on the collection.
We currently add to the collection entity then call save changes. We tried modifying the entities and the context so that we could add directly to the DbSet, but it made no difference.
The code in question:
Our entities are as follows:
The SQL that EF generated was this:
The test that we set up expected the extension and type to be in ascending order.
Our workaround is to call SaveChangesAsync() after adding each entity to the parent.
Further technical details
EF Core version: 2.0.2 Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Windows 10 IDE: Visual Studio 2017 15.6.6