Reputation: 384
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
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