J'ai les deux modèles suivants, PatientRegistry et PartnerRegistry. La relation entre ces modèles est une à plusieurs.

J'essaie de lire l'enregistrement et celui qui lui est associé, mais j'obtiens un JSON cassé à PartnerRegistry. La seule façon dont je l'ai fait fonctionner est d'utiliser Automapper, mais pourquoi cela se produit-il? Dois-je appeler le contexte du deuxième modèle? Je crois comprendre qu'EF le fera automatiquement une fois la relation établie.

MODIFIER

J'ai enlevé un accessoire juste pour raccourcir la liste

[Table("PatientsRegistry")]
    public class PatientRegistry
    {   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Display(Name = "Record Id")]
        public long RecordId { get; set; }
        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Display(Name = "Patient File Number")]
        public long PatientFileId { get; set; }
        [Required, StringLength(50)]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }
        [Required, StringLength(50)]
        public string SecondName { get; set; }
        [Required, StringLength(50)]        
        public string LastName { get; set; }
        public int GenderId { get; set; }
        public Gender Gender { get; set; }
        public DateTime DateCreated { get; set; } = DateTime.UtcNow;
        [Timestamp]
        public byte[] RowVersion { get; set; }
        public ICollection<PartnerRegistry> Partners { get; set; }
        public PatientRegistry()
        {
            Partners = new Collection<PartnerRegistry>();
        }

    }
public class PartnerRegistry
    {   
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long RecordId { get; set; }
        public long PatientFileId { get; set; }
        public long PartnerFileId { get; set; }
        public PatientRegistry PatientsRegistry { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime? EndDate { get; set; }

    }

Et mon contrôleur est

 [HttpGet("{id}")]
    public async Task<IActionResult> getAll(long Ids)
    {
          var patient = await context.PatientsRegistry
        .Include(pt => pt.Gender)
        .Include(pt => pt.Partners)
        .SingleOrDefaultAsync(pt => pt.PatientFileId == Ids);

        return Ok(patient);
    }

La sortie est

{
    "recordId": 1,
    "patientFileId": 1111,
    "firstName": "John",
    "secondName": "M",
    "lastName": "Doe",
    "genderId": 1,
    "gender": {
        "id": 1,
        "name": "Male"
    },
    "dateCreated": "2017-11-25T08:40:07.75444",
    "rowVersion": "AAAAAAAAB9E=",
    "partners": [{
                "recordId": 1,
                "patientFileId": 1111,
                "partnerFileId": 2222

Vous pouvez remarquer qu'il manque des propriétés qui n'ont pas été mappées par ef! Les propriétés qui n'ont pas été renseignées sont, StartDate et EndDate

2
JSON 26 nov. 2017 à 01:18

3 réponses

Meilleure réponse

Une solution rapide:

public class PartnerRegistry
{   
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long RecordId { get; set; }
    public long PatientFileId { get; set; }
    public long PartnerFileId { get; set; }

    [JsonIgnore]  // add this
    public PatientRegistry PatientsRegistry { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; }
}

Edit, un petit mcve:

class Patient
{
    public string  Name { get; set; }
    public ICollection<Partner> Partners { get; set; }
}

class Partner
{
    public string Name { get; set; }
    //[JsonIgnore]
    public Patient Patient { get; set; }
}

Avec ces classes et partenaires remplis,

string text = JsonConvert.SerializeObject(patient1);

Jettera

Newtonsoft.Json.JsonSerializationException: 'Boucle d'auto-référencement détectée pour la propriété' Patient 'de type' App1.Patient '. Chemin "Partenaires [0]". "

1
Henk Holterman 25 nov. 2017 à 23:27

Mise à jour:

Aussi j'ai trouvé que ce problème peut être résolu globalement via cette configuration,

    services.AddMvc()
    .AddJsonOptions(options => 
     options.SerializerSettings.ReferenceLoopHandling =
     Newtonsoft.Json.ReferenceLoopHandling.Ignore);

Réf.

1
JSON 20 févr. 2018 à 03:24

Mettez l'attribut [ScriptIgnore] sur la propriété PatientRegistry de la classe PartnerRegistry. Cet attribut est disponible depuis System.Web.Script.Serialization. Il peut y avoir des références circulaires interrompant la sérialisation / désérialisation.

1
Johan van Tonder 25 nov. 2017 à 23:23
47491043