Reputation: 21
I recently started diving deeper into the Clean Architecture realm with the Ardalis project template. Here is a link to the nuget package to get started with the template.)
I have been reading about the benefits of using integers and Guids as table IDs which were explained well and very brief here. By using the Ardalis Template there is a BaseModel created with an int set to the default Id. But to get Guids working and if you still want to use ints for some other table you can abstract your own model (if you want) like this:
public abstract class BaseModel<T>
{
// ...
public T? Id { get; set; }
// ...
}
This will work when you implement an entity which will use the inherit the base class as such:
public class DatabaseEntity : BaseModel<Guid>
{
// This will then create the Guid Id field
}
This is then the normal json value from the api:
{
"id": "a84c8f7e-77ef-49c9-908e-2bbbce59cdd1"
}
The problem comes in with having multiple models and setting up a Parent and Child relationship.
public async Task<Child> GetChildByParent(Guid parentId, Guid childId)
{
// ...
}
I have read that this type of scenarios can be solved by strongly typed Ids per model with readonly record structs which is quite efficient but with one slight caveat. You need to write a object converter to convert the unmodified json like the following into a "normal" object.
{
"id": {
"id": "a84c8f7e-77ef-49c9-908e-2bbbce59cdd1"
}
},
Using the StronglyTypeId package is great and is suited for most projects to generate the required converter per type. This however still takes 1 more operation per object retrieved from the database to execute.
My question:
If it is possible, how can I create a strongly typed id (value type) that work as a GUID and does not require any conversion code to work?
An example would be something like a struct inheriting another struct (if you want to reuse the same functionality but only change the type):
public readonly record struct ContributerId : Guid // this is impossible at the moment
{
}
Upvotes: 0
Views: 232
Reputation: 314
if you are talking about the strongly type Ids so it is something else per scenario like
public class Student : BaseEntity<Guid>
{
public Student (Guid studentId, Guid teacherId, string name)
{
// Initialization logic
}
}
so, in the above case there is possibility of id swapping so to handle this we can make type for each entity Id and then pass to it .
public record StudentId(Guid Value);
public record TeacherId(Guid Value);
Then do it in something like that
public class Student : BaseEntity<StudentId >
{
public Student (StudentId studentId, ParentId teacherId, string name)
{
// Initialization logic
}
}
Upvotes: 0