Typed ids to plain id
My model is something like How would I transform that
UserId
into a type that's valid in the database, like the Guid or int that's inside of the UserId
?23 Replies
And will typed ids be problematic in the long run?
That's just a pattern I saw and that could be applied in my applications, dunno if it's good or not
You can use EFCore Value Converters for this:
And then register it in the DBContext
nani
question... what.
I just assumed you use EFCore
yea, it's ef
I dunno what all of that is though
Value Conversions - EF Core
Configuring value converters in an Entity Framework Core model
yep, I'm still lost :d
So EFCore has the capability to convert your dotnet types like your custom UserId object to an database compatible type like string or uuid or whatever.
This is done by defining how this conversion is done in a class inheriting from
ValueConverter<T, TPrimitive>
.
So if UserId
wraps a Guid
you would need to define a class UserIdConverter: ValueConverter<UserId, Guid>
and implement it.
Then to tell EFCore that this exists and that you use it, you override the OnConfigureConventions
Method in your DbContext
and tell EFCore that it should use this conversion for each property of a given type. Like UserId
.
Clear so far?is that just a weird mapper?
You could call it a mapper I guess.
also what's even that
ConfigureConventions
thing? I've never seen that and it's not on the link you've sentYou got some class inheriting from
DbContext
right?yea ofc
DbContext
has a method called ConfigureConventions
, which you can override.
In there you can define settings and conventions which then apply to all models in the context.https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations#bulk-configuring-a-value-converter also it is explained in the post.
Value Conversions - EF Core
Configuring value converters in an Entity Framework Core model
note to self: don't used typed ids
that's kinda weird and complex for absolutely no reason
I think that's the wrong takeaway. Typed IDs are great, they just require some setup to use and you need to know about some of their caveats.
There are source generators which do all the code repition for you like https://github.com/andrewlock/StronglyTypedId
GitHub
GitHub - andrewlock/StronglyTypedId: A Rosyln-powered generator for...
A Rosyln-powered generator for strongly-typed IDs. Contribute to andrewlock/StronglyTypedId development by creating an account on GitHub.
It's also not just typed IDs. Whenever you start to encapsulate primitives into value objects, you will need ValueConverters in C#.
and that'll be a problem for me since I'll need to define that in every context, right?
I plan to have 2 contexts, so yea
You could just have an extension method containing all the shared config.
In the end you are correct.
Strongly typed IDs require some thinking and additional code to set up in the first place.
It is easier to just use incrementing integers as Ids everywhere.
And if the trade off of better readability and type safety isn't worth the hassle in your opinion, then don't use them.
readability? kinda? no?
it is type safe, yes, but I still think it's too complex just for type safety
I'll try it in testing for a bit, but I'll probably not use it
thx for the help
Readability is big part.
Consider a method signature like this.
public async Task UpdateComment(int userId, int blogId, int commentId, string newContent)
And compare that to
public async Task UpdateComment(UserId userId, BlogId blogId, CommentId commentId, string newContent)
The second one is way more readable in my opinion. It is clear what each parameter does, without depending on the name of the variable to tell you. In this case the first one is fine and readable, but consider someone else writing code and not being very good with namings.
public async Task UpdateComment(int user, int postId, int postResponseId, string test)
I'm just thinking that we're in modern day, where you can just
ctrl+k
(or whatever your keybind is) and see the param names.
That's why I only think of the type safety of it, I don't see any difference between these two
even if the dev is bad at naming, some name will still be there too, so that shouldn't be a problem, unless you're a go developer (single named variables)