Samu R
Samu R

Reputation: 384

C# include relationship object from many to many with automapper

I'm trying to map from Role to RoleModel including the Feature/FeatureModel, but I haven't been able to make it work properly.

It returns the role but does not include the features:

{
    "name": "Backend",
    "description": "Backend role",
    "roleFeatures": [],
    "roleUsers": [],
    "updatedDate": "2023-02-03T16:14:54.036441",
    "deletedDate": null,
    "id": "82a443bd-81d3-4460-8a67-08db0601365e",
    "createdDate": "2023-02-03T16:14:54.036441",
    "deleted": false
}

This is the map I created:

 CreateMap<Role, RoleModel>()
            .ForMember(rm => rm.RoleFeatures, opt => opt
                .MapFrom(r => r.RoleFeatures.Select(y => y.Feature).ToList()))
            .MaxDepth(1);

These are the classes: Role

public class Role : BaseRecord
{
   public string Name { get; set; }
   public string Description { get; set; }
   public ICollection<RoleFeature> RoleFeatures { get; set; }
   public ICollection<RoleUser> RoleUsers { get; set; }
}

RoleModel

public class RoleModel : BaseRecordModel
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public ICollection<RoleFeatureModel> RoleFeatures { get; set; }
        public ICollection<RoleUserModel> RoleUsers { get; set; }
    }

RoleFeature

  public class RoleFeature
    {
        public bool Read { get; set; }
        public bool Write { get; set; }
        public bool Edit { get; set; }
        public bool Delete { get; set; }
        public Guid RoleId { get; set; }
        public Role Role { get; set; }
        public Guid FeatureId { get; set; }
        public Feature Feature { get; set; }
    }

RoleFeatureModel

 public class RoleFeatureModel
    {
        public Guid RoleId { get; set; }
        public Guid FeatureId { get; set; }
        public bool Read { get; set; }
        public bool Write { get; set; }
        public bool Edit { get; set; }
        public bool Delete { get; set; }
        public RoleModel Role { get; set; }
        public FeatureModel Feature { get; set; }
    }

Previously I was creating a simple map:

 CreateMap<Role, RoleModel>();

But I was getting an object cycle error, now I get the roleModel but the roleFeature list is empty.

Upvotes: 0

Views: 86

Answers (1)

Rusmirnator
Rusmirnator

Reputation: 133

I'm gonna listen to what my guts tell me - you are querying for the roles in lazy loading manner (default), aren't you?

You have to include related members explicitly, for example:

var resultSet = await _context.Roles.Include(r => r.RoleFeatures).ToListAsync();

Include() method enforces so called eager loading, providing you not only with requested data, but also its related members.

It also can be chained e.g.:

var resultSet = _context.Roles.Include(r => r.RoleFeatures)
                              .Include(r => r.RoleUsers)
                                  .ToListAsync();

OR

If you are already using eager loading.

Instead of constraining your mapper with MaxDepth(1), go to your ConfigureServices() (in your Startup.cs or Program.cs) method, and configure JsonSerializer in a way that suits you the best, for example:

services.AddNewtonsoftJson(options =>
{
    options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
    options.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
    options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.All;
});

Above example uses Newtonsoft.Json, but you can achieve the same effect reffering ReferenceLoopHandling with System.Text.Json serializer.

Upvotes: 1

Related Questions