-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expose Added, Updated, Deleted, etc from ChangeTracker, Introduce ChangeSet concept #21518
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
@juliusfriedman We will discuss, but I doubt that we will implement anything that is designed to recover from database constraint violations. We generally follow the philosophy that a constraint exception indicates an application error, rather than a recoverable state. |
Yea so would I but the problem is checking the failing SQL there is no violation and the message is bogus. I am still looking into it btw. Keep in mind, especially with cloud... I may have multiple writers and I should be able to gracefully fail / sync. and Yes I know that is what database replication is for. The concept is powerful on it's own e.g. just for the order of operations without the Failures but I would highly suggest for their allowance. I have verified that a BulkCopy with almost the same exact SQL is NOT failing the only difference I see is the MERGE vs the BULK which unfortunately indicates a bug in EF 3.1.5. |
We discussed this as a team and agreed that this is not something we want to support in EF Core. |
Can you please take a few moments to review the failing SQL and give your opinion as to why it would fail and a Thank you again for your time! |
@juliusfriedman For that, please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate. |
Note that after #7829 is fixed |
Dear sir I have code similar to the following: catch(DbUpdateException dbex)
{
foreach(var e in dbex.Entries)
{
if(e.Entity is Something s)
{
Trace.WriteLine($"Someting ({s.ID}) Failed Insert for some reason");
}
else if (e.Entity is SomethingElse se)
{
Trace.WriteLine($"SomethingElse ({se.ID}) Failed Insert for some reason");
}
else
{
Trace.WriteLine($"Something other thing Failed Insert for some reason..");
}
}
} I was wondering simply now that I have this ability to determine which entities failed, how can I remove them from the Snapshot which has already been attempted by Thank you for your time! |
e.State = EntityState.Detached; |
When I am inserting a large number of records (for instance synchronizing with an external database or provider), sometimes I receive an exception that the insert fails on a foreign key constraint (which is technically impossible because that would be invalid referential integrity...)
I would like the option to either not get this exception by having a
IgnoreFailedInserts
or perhaps even more fine grained control but without looping over the entireChangeSet
, e.g. the ability to get just the failedInserts
,Updates
,Deletes
etc.For example when implementing soft delete...
I think this would be much better if I could just take action on the
FailedUpdates
,FailedInserts
andFailedDeletes
while not having to act on the ones which would have otherwise been successful.Since you already do the insert in a way which you can detail which one fails you should report that information back to the user so they can take the appropriate action.
e.g. having to loop all tracked entries is not that useful especially if the context is loaded with a lot of data unrelated to the insert.
I think also having the entity which failed for whatever reason gives you then the chance to make sure it hasn't already been acted upon and then if not take subsequent action or perhaps a merge based approach, whatever your application requires.
An example of the SQL which fails is:
Failing SQL Insert Example:
Column names and some values have been changed to protect the identity of the application and it's data
The error message should contain the param / record id which failed the insert.
API Proposal
Expose a
ChangeSet
or similar type with the aforementioned properties as an overload fromDetectChanges
which can be use instead ofChangeTracker.Entries()
such as:Expected Usage
When a entity already exists I can either choose to perform a query to determine if I have the same information and if not perform an update instead.
Current Practices
Calling
SaveChanges
(async) etcCatching the myriad of exceptions and breaking them out into appropriate logic which is not only a performance hit but usually results in similar call paths in the common case.
Benefits
Risks
Low for the everything except
Failures
.Memory usage associated with the extra information (could be mitigated with other switches and knobs)
Example implementation for Modifications (not optimized)
The
Failures
could also returnSystem.Collections.Generic.IEnumerable<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry>
just thinking about if the same thing will arise where I only want to handle update failures or handle them differently (possibly based on type) etc, so aChangeSet
with these properties which would be propagated back to the user based on the other switches and knobs seems like how it should be done.In the end the user should say per
ChangeSet
if inserts should happen before updates or deletes etc as well as how to handle failures very easily.What is a ChangeSet
It is a class which determines all of the data within a 'Snapshot' and how it will be processed on the sever (in what order etc)
It can provide information on what did not insert and why allowing you to quickly remedy
It can provide a way for you to put a bunch of queries into the context and control the order of operations rather than letting the change tracker attempt to do this.
The text was updated successfully, but these errors were encountered: