How can I replace `Id` field of Entity class to DomainEntityName+Id field of a domain class in Clean Architecture?

144 Views Asked by At

I am working on an application that uses Clean Architecture in .net core. The domain entities are inherited from AggregateRoot which is further inherited with the Entity class. This entity class has Id field which means I now have Id in all my domain entities. It works fine if all my domain entities have an Id field. Below is the code sample.

public abstract class Entity : IEquatable<Entity>
{
    protected Entity(int id) => Id = id;

    protected Entity()
    {
    }
}

public abstract class AggregateRoot : Entity
{
    protected AggregateRoot(int id)
        : base(id)
    {
    }
}

public sealed class User : AggregateRoot
{

}

public sealed class Directory : AggregateRoot
{

}

I have a different way of handling the Id fields. I am using the DomainEntityName+Id. e.g., For entities User & Directory has UserId & DirectoryId respectively. I have the same ids in the database as well. I don't want to use the Id field and want to replace it with UserId or DirectoryId. Please suggest how can I achieve this.

I did try to keep both fields and populate both with the value from the database using the configuration below:

builder
.Property(x => x.DirectoryId)
.HasColumnName("DirectoryId");

builder
.Property(x => x.Id)
.HasColumnName("DirectoryId")
.ValueGeneratedNever();

but this has thrown the exception:

System.InvalidOperationException: 'Directory.DirectoryId' and 'Directory.Id' are both mapped to column 'DirectoryId' in 'Directories', but the properties are contained within the same hierarchy. All properties on an entity type must be mapped to unique different columns.

Edited Question:

public class Directory : AggregateRoot  
{       
    [NotMapped]         
    public int DirectoryId { get; init; }       
    public string Name { get; init; } = string.Empty;   
} 

public void Configure(EntityTypeBuilder<Directory> builder)     
{       
    builder.Property(x => x.DirectoryId).HasColumnName("DirectoryId");          
    builder.Property(x => x.Id).HasColumnName("DirectoryId").ValueGeneratedNever();     
}

The AggregateRoot has an Entity class with Id field. With this change the DirectoryId is set with zero value.

1

There are 1 best solutions below

0
Svyatoslav Danyliv On

I would suggest to reuse Id property storage and do not map DirectoryId do database:

public class Directory : AggregateRoot  
{       
    public int DirectoryId { get => Id; init => Id = value; }
    public string Name { get; init; } = string.Empty;   
} 

public void Configure(EntityTypeBuilder<Directory> builder)     
{       
    builder.Ignore(c => c.DirectoryId);
    builder.Property(x => x.Id).HasColumnName("DirectoryId").ValueGeneratedNever();     
}