Can not Adapt model with cycle in Mapster

47 views Asked by At

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.

1

There are 1 answers

0
Ali NGame On BEST ANSWER

Finally, I found that the reason was simply lack of a setter in my ViewModel for PartyGroups

#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

Simply add a setter even a private setter will solve the problem.

    #region Party Groups

    public List<PartyGroupViewModel> PartyGroups { get; private set; } = new List<PartyGroupViewModel>();

    #endregion Party Groups