-
-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No easy way to determine which constraint failed. #35
Comments
Do all the DB Providers that this library supports contain all that information? I can't find it for |
Right,
This package could try to extract these values from a message (or elsewhere) and just have corresponding properties nullable if not all providers have them in an exception. Another option would be to store that info in a Data property (no key = no value provided by the exception) and |
@STeeL835 Message is not reliable because it is different based on the language of the database server. |
@Giorgi You're right.. Well, it could be a "preview" feature, that doesn't guarantee the values (nullable properties still fit) - at least something. Maybe |
Given that it won't work in all cases even for SqlServer, the value added by those properties will be very low while the number of cases it won't work will be very high. In my opinion parsing of error messages generated by different databases in different languages should be a separate project and not part of this library. |
Still don't understand, why not. People with providers that support these properties will be happy, people with providers like |
@STeeL835 Which database providers report the constraints/tables that caused the error? |
For example NpgSql, like in the OP's example. Don't know about the others, though |
One solution that would be more reliable than parsing the message to extract the index name could be: Get a list of all the index names from the var indexNames = context.Model.GetEntityTypes().SelectMany(x => x.GetIndexes())
.ToFrozenDictionary(x => x.GetDatabaseName()!, x => x.Properties); Then you could search the error message for each of the index names, and match that way. It's not perfect but it'd solve at least for the language differences. Messages that don't contain the index name at all will of course not work. |
That sounds like a good idea. It will not work for indexes that exist in the database but not in the model but that can be documented. |
@NickStrupat The good news is that it works for all other databases. |
For Sqlite, it seems the unique constraint message follows the pattern of a Anyway, a solution for Sqlite could be to cache a lookup structure where the keys are a list of the column names in each index, and then you could loop over those trying to match as many as possible in the message. Then you could use that key to look up the constraint name. Something like this to make the lookup structure: var indexNameLookup = context.Model.GetEntityTypes().SelectMany(x => x.GetIndexes()).ToFrozenDictionary(
i => i.Properties.Select(p => i.DeclaringEntityType.GetTableName() + '.' + p.GetColumnName()).ToList(),
i => i.GetDatabaseName()!
); |
@NickStrupat @mjamro @STeeL835 This is now implemented and live in the 8.1.0 version of the library. See the ReadMe for more details. |
Including Sqlite support? |
No, haven't implemented it for SQLite. |
Problem
When entity has more than one constraint there is no easy way to dermine which constraint failed. You need to resort to underlying DB provider exception, which slightly defies the idea behind this library of having high-level exception handling.
Currently you need to do it like that:
Proposal
Add fields to the exception to hold additional information like name of the constraint that failed. DB Providers typically contain that in their exceptions, so it's only a matter of mapping them to classes like
UniqueConstraintException
That would include:
This would simplify the catch block like that:
I can provide a PR if you approve.
The text was updated successfully, but these errors were encountered: