I have a model with cycle navigation properties. I can't adapt this model to viewmodel using Mapster completely. PartyGroups and it's details are not included, However PartyPhones arre included without any problem.
My PartyModel :
public class PartyModel : Entity
{
#region First Name
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 256, MinimumLength = 3)]
public string FirstName { get; set; } = string.Empty;
#endregion First Name
#region Last Name
[StringLength(maximumLength: 256, MinimumLength = 3)]
public string LastName { get; set; } = string.Empty;
#endregion Last Name
#region Birthdate
[DataType(System.ComponentModel.DataAnnotations.DataType.Date)]
public DateTime? Birthdate { get; set; }
#endregion Birthdate
#region Party Type
public PartyType Type { get; set; } = PartyType.Unknown;
#endregion Party Type
#region Navigation Properties
#region Phone Numbers
[ForeignKey(nameof(PartyPhoneModel.PartyRef))]
public virtual ICollection<PartyPhoneModel> PhoneNumbers { get; } = new List<PartyPhoneModel>();
#endregion Phone Numbers
#region Party Groups
public virtual ICollection<PartyGroupModel> PartyGroups { get; } = new List<PartyGroupModel>();
#endregion Party Groups
#endregion Navigation Properties
}
My PartyViewModel:
public class PartyViewModel : ViewModel
{
#region First Name
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 256, MinimumLength = 3)]
[System.ComponentModel.DataAnnotations.Display
(Name = nameof(NG.Framework.Resources.Labels.FirstName), ResourceType = typeof(NG.Framework.Resources.Labels))]
public string FirstName { get; set; } = string.Empty;
#endregion First Name
#region Last Name
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 256, MinimumLength = 3)]
[System.ComponentModel.DataAnnotations.Display(
Name = nameof(NG.Framework.Resources.Labels.LastName), ResourceType = typeof(NG.Framework.Resources.Labels))]
public string LastName { get; set; } = string.Empty;
#endregion Last Name
#region Birthdate
[DataType(System.ComponentModel.DataAnnotations.DataType.Date)]
[System.ComponentModel.DataAnnotations.Display(
Name = nameof(NG.Framework.Resources.Labels.Birthdate), ResourceType = typeof(NG.Framework.Resources.Labels))]
public DateTime? Birthdate { get; set; }
#endregion Birthdate
#region Party Type
public PartyType Type { get; set; } = PartyType.Unknown;
#endregion Party Type
#region Navigation Properties
#region Phone Numbers
public List<PartyPhoneViewModel> PhoneNumbers { get; private set; } = new();
#endregion Phone Numbers
#region Party Groups
public List<PartyGroupViewModel> PartyGroups { get; } = new List<PartyGroupViewModel>();
#endregion Party Groups
#endregion Navigation Properties
}
GroupModel:
public class GroupModel : Entity
{
#region Title
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 150, MinimumLength = 3)]
public string Title { get; set; } = string.Empty;
#endregion Title
#region Description
[StringLength(maximumLength: 150, MinimumLength = 3)]
public string Description { get; set; } = string.Empty;
#endregion Description
#region Navigation Properties
public virtual ICollection<PartyGroupModel> PartyGroups { get; } = new List<PartyGroupModel>();
#endregion Navigation Properties
}
GroupViewModel:
public class GroupViewModel : ViewModel
{
#region Title
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 150, MinimumLength = 3)]
public string Title { get; set; } = string.Empty;
#endregion Title
#region Description
[StringLength(maximumLength: 150, MinimumLength = 3)]
public string Description { get; set; } = string.Empty;
#endregion Description
#region Navigation Properties
public List<PartyGroupModel> PartyGroups { get; } = new List<PartyGroupModel>();
#endregion Navigation Properties
}
PartyGroupModel:
public class PartyGroupModel : SlaveEntity
{
#region PartyId
[Required]
public Guid PartyId { get; set; }
#endregion PartyId
#region GroupId
[Required]
public Guid GroupId { get; set; }
#endregion GroupId
#region Navigation Properties
#region Party
public virtual PartyModel Party { get; } = new();
#endregion Party
#region Group
public virtual GroupModel Group { get; } = new();
#endregion Group
#endregion Navigation Properties
}
PartyGroupViewModel:
public class PartyGroupViewModel : SlaveViewModel
{
#region PartyId
[Required]
public Guid PartyId { get; set; }
#endregion PartyId
#region GroupId
[Required]
public Guid GroupId { get; set; }
#endregion GroupId
#region Navigation Properties
#region Party
public PartyViewModel Party { get; } = new();
#endregion Party
#region Group
public GroupViewModel Group { get; } = new();
#endregion Group
#endregion Navigation Properties
}
PartyPhoneModel:
public class PartyPhoneModel : SlaveEntity
{
#region Party Ref
[ForeignKey(nameof(Party))]
public Guid PartyRef { get; set; }
#endregion Party Ref
#region Phone Number
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 20, MinimumLength = 8)]
public string PhoneNumber { get; set; } = string.Empty;
#endregion Phone Number
#region Phone Type
public PartyPhoneTypeEnum Type { get; set;} = PartyPhoneTypeEnum.Unknown;
#endregion Phone Type
#region Navigation Properties
public virtual PartyModel Party { get; } = new();
#endregion Navigation Properties
}
PartyPhoneViewModel:
public class PartyPhoneViewModel : ViewModel
{
#region Phone Number
[Required(AllowEmptyStrings = false)]
[StringLength(maximumLength: 20, MinimumLength = 8)]
[System.ComponentModel.DataAnnotations.Display(
Name = nameof(NG.Framework.Resources.Labels.PhoneNumber), ResourceType = typeof(NG.Framework.Resources.Labels))]
public string PhoneNumber { get; set; } = string.Empty;
#endregion Phone Number
#region Phone Type
public PartyPhoneTypeEnum Type { get; set; } = PartyPhoneTypeEnum.Unknown;
#endregion Phone Type
}
Thanks.
Finally, I found that the reason was simply lack of a setter in my ViewModel for PartyGroups
Simply add a setter even a private setter will solve the problem.