-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Changed Insert methods and interface to return id as long. #640
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
Conversation
The conetrib extension insert methods were throwing when ids of greateer than 2147483647 were returned. This occured because they id was being cast to an int. Changing to long fixes the problem.
|
The problem is this is a huge breaking change. We can't just change it. Instead, we need to create generic overloads which has just kept getting punted down the priority list :-/ Also note: this only resolves one case. What if the ID is a GUID? That's why we need a generic solution instead. |
|
No worries Nick. The fix works for our codebase so we will incorporate the source and retire the contrib dependency |
|
Would the generic solution involve insert plus the int overload calling insert or would it be better to pass in a conversion func? If the former, then how to ensure proper casting for every case? Plenty of open issues for similar casting during mapping on queries. Perhaps the same typemapping strategy should be used to map return values based on T. |
|
Oops, forgot to escape insert<T> |
|
@phillip-haydon The version I'm picturing isn't very complicated, it just need doing. And honestly Contrib just needs a lot of love in general that we haven't had time for. Here's what exists today: public static long Insert<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : classWhat I'm picturing (roughly, the point is generics) is: public static TKey Insert<T, TKey>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : classAnd the existing public static long Insert<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : class =>
Insert<T, long>(connection, entityToInsert, transaction, commandTimeout)What this doesn't solve is composite keys which are across multiple fields. But at a larger scope, that's a bigger problem with Dapper.Contrib in general. Any thoughts on such an approach? Honestly, we should make a proper API discussion here as an issue with proposed things on all providers. We want |
|
I'm a bit of a noob as far as contributing, but I'd like to help with this. For sure about the composite keys, was thinking about that too. Also, not sure if Is always going to work. As I'm gathering that some types need special mapping rules, especially for supporting composite keys. I will take a stab at a first version though, without the composite case, as the 80% case is int, long or Guid. I cloned the repo recently, but I believe I haven't got it running local yet...perhaps some additional steps to take first. |
|
Haha @NickCraver, you pulled in the wrong Phillip :) |
|
Ok, got a bit of a start here. One issue is really with the SQL specific adapters and that interface. Those each return int as well. |
|
This is a bit of a trip down the rabbit hole. In order to test this, I would need to install ALL supported databases OR rewrite most of Contrib and core to make it testable. If I could fake IDbConnection it would be doable, but QueryMultiple and other extension methods are used. I've never faked an extension method before - going to see if its possible. In the long view, I may be taking things in a direction that aren't suitable for the goals of Dapper. Dapper seems to use a lot of static and there may be a specific reason for that. They are hard to double in unit test contexts, which is presenting obstacles to ramping up for making changes to Contrib. I would like to contribute, but I don't want to spin gears too much in the wrong direction. Some ideas I've had so far along the way - there are a few main components in contrib: SqlGeneration, mapping (properties to SQL, results to properties), caching, and glue to Dapper core. At the moment, these are sort of mashed together. So far, most of the issues with Contrib are related to results mapping. Currently, only the int id PK is supported. It should support different types and combo-keys. Maybe give the option to return the whole row to an object as well, else how to handle multiple values for the multi-part key? Possibly separate type just for that? Dynamic? Think about if the return type is TKey, that's essentially saying TKey could be Person object unless its limited to decimal, long, Guid, etc. |
|
Well, did some experimentation. Returning dynamic from the Insert would work IFF the SQL itself actually returned the Guid, but it doesn't in MySql anyways. Needs more work. One drawback to returning dynamic is that it has to be cast by the consumer, |
|
Until we have a generic solution, can we have an official build with long return type? |
|
Such a build would be a breaking change. We'll try and get this into the next major version. I'm working on MiniProfiler and Marc's working on StackExchange.Redis now, then we'll circle back to Dapper for a v2 pass. It's just too much to coordinate the 3 at once. |
|
I'm closing this out as we won't be going this way, but have referenced the discussion for fixing this in the v2 releases, link will appear below this in a few minutes. |
The contrib extension insert methods were throwing when ids of greater
than 2147483647 were returned. This occurred because they id was being
cast to an int. Changing to long fixes the problem.