Home > Software engineering >  construct new object of 3 relations
construct new object of 3 relations

Time:11-01

I have database schema of 4 tables. Tenants can have many users, users can have many tenants. User can have many roles in tenant.

database schema

Using EF Core, I need to get all users by tenant_id. User DTO need to contain list of roles. So far, I thought of something like this:

var users = dbContext.UserTenantsRoles
                     .Where(u => u.TenantId == tenantId)
                     .Select(u => new GetUserDto
                                  {
                                      Id = u.User.Id,
                                      Email = u.User.Email,
                                      CreatedAt = u.User.CreatedAt,
                                      Role = u.Role.RoleName.ToString()
                                  });

DTO:

public class GetUserDto
{
    public Guid Id { get; set; }
    public string Email { get; set; }
    public DateTime CreatedAt { get; set; }
    public string Role { get; set; }
}

Models:

[Index(nameof(Email), IsUnique = true)]
public class User
{
    public Guid Id { get; set; }
    public string Email { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime? ModifiedAt { get; set; }

    public List<UserTenantRole> UserTenantsRoles { get; set; }

[Index(nameof(Name), IsUnique = true)]
public class Tenant
{
    public Guid Id { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime? ModifiedAt { get; set; }
    public DateTime? DeletedAt { get; set; }
    public string Name { get; set; }

    public List<UserTenantRole> UserTenantsRoles { get; set; }
}

[Index(nameof(RoleName), IsUnique = true)]
public class Role
{
     public Guid Id { get; set; }
     public RoleName RoleName { get; set; }

     public List<UserTenantRole> UserTenantsRoles { get; set; }
}

public enum RoleName
{
    User,
    Admin
}

public class UserTenantRole
{
    public Guid TenantId { get; set; }
    public Tenant Tenant { get; set; }

    public Guid UserId { get; set; }
    public User User { get; set; }

    public Guid RoleId { get; set; }
    public Role Role { get; set; }
}

But I want this DTO to have list of roles and user Ids not repeating in user list. Is this possible in 1 query or should I iterate over this user list and construct new list?

CodePudding user response:

Try the following query:

var users = dbContext.Users
    .Where(u => u.UserTenantsRoles.Any(utr => utr.TenantId == tenantId))
    .Select(u => new GetUserDto
    {
        Id = u.Id,
        Email = u.Email,
        CreatedAt = u.CreatedAt,
        Role = u.UserTenantsRoles
            .Where(utr => utr.TenantId == tenantId)
            .Select(utr => utr.Role.Name)
            .ToList()
    });
  • Related