2011-11-02 16 views
11

Ho un'entità framework entità che desidero serializzare come oggetto json. Mi sono guardato intorno e ho scoperto che json.net (http://james.newtonking.com/projects/json-net.aspx) dovrebbe essere in grado di serializzare oggetti con riferimenti circolari "out of the box". Così ho provato a utilizzarejson.net; serialize entity framework object (errore di riferimento circolare)

string json = JsonConvert.SerializeObject(/* my ef entity */); 

Ma sto ancora ottenendo lo stesso errore. Il problema potrebbe essere che ho bisogno di usare ReferenceLoopHandling.Ignore e un ContractResolver, ma non sono sicuro di come usarli. Ogni aiuto è molto apprezzato! Grazie

+0

possibile duplicato del [Serializzare Entity Framework oggetti in JSON] (http://stackoverflow.com/questions/657939/serialize-entity-framework-objects-into- json) –

+2

@CraigStuntz no, perché non voglio mappare le proprietà su un nuovo oggetto maunalmente. E sto chiedendo come si può fare usando JSON.NET – Johan

+0

La soluzione proposta funzionerà per JSON.NET.Se preferisci gestire riferimenti circolari piuttosto che una dichiarazione di assegnazione, beh, dipende da te. Ma JSON.NET non significa che l'altra soluzione non funzionerà. –

risposta

2

La mia soluzione era semplicemente rimuovere il riferimento padre sulle entità figlio.

Quindi nel mio modello, ho selezionato la relazione e modificato il riferimento padre come Interno anziché Pubblico.

Potrebbe non essere una soluzione ideale per tutti, ma ha funzionato per me.

14

Per aggirare questo ho convertito le mie entità in codice prima basato su POCO. Per fare ciò, fare clic con il tasto destro del mouse all'interno della finestra edmx e selezionare:

Aggiungere la voce di generazione codice> scheda Codice> EF POCO Entity Generator.

Nota che potrebbe essere necessario installarlo con nuget se non lo vedi.

In fase di esecuzione, tuttavia, EF aggiunge classi proxy a tali oggetti per scopi di monitoraggio ma tendono a rovinare il processo di serializzazione. Per evitare che questo si può semplicemente impostare ProxyCreationEnabled false come segue:

var context = new YourEntities(); 
context.Configuration.ProxyCreationEnabled = false; 

var results = context.YourEntity.Take(100).ToList(); 

È quindi possibile tornare tranquillamente Json.NET dati serializzati omettendo il riferimento di default loop come segue:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new JsonSerializerSettings { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    }); 
+4

+1 per 'ReferenceLoopHandling.Ignore' - mi ha salvato la giornata! – nrodic

1

Prova questa: First facendo in modo poco o modello ha DataContract, DataMemeber e rimuovere word..then tasto virtuale ..

public string Get() 
    { 
     var list = _languageRepository.GetMany(l => l.LanguageTrans.FirstOrDefault().CultureCode == "en").ToList(); 

     string json = JsonConvert.SerializeObject(list, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); 

     return json; 
    } 
+0

In questo modo è possibile mantenere le entità correlate ... – Bryant

9

Un'altra soluzione sarà l'aggiunta di [JsonIgnore] attribut e alle proprietà di navigazione.

Ad esempio:

using System; 
using System.ComponentModel.DataAnnotations.Schema; 

[Serializable] 
public class Entity 
{ 
    public int EntityID { get; set; } 
    public string EntityName { get; set; } 

    [JsonIgnore] 
    public virtual Parent Parent { get; set; } 
    [JsonIgnore] 
    public virtual List<Child> Children { get; set; } 
} 
+0

Questa è la risposta corretta, le entità dovrebbero fare riferimento l'una all'altra. Ma è necessario ignorare la proprietà dell'entità master nel figlio. – Darren

+1

Ma cosa succede se voglio vedere la relazione dal punto di vista degli elementi figlio? –

6

ho usato la seguente soluzione per clonare i miei soggetti, senza trucchi in cui gli attributi dati riguardanti richieste sulle entità e mio tavolo riferimenti circolari ricevuti conservati. Avevo persino delle entità che puntavano l'una sull'altra senza problemi. La libreria richiesta per la serializzazione è Json.Net (la dll Newtonsoft.Json). utilizzo

private static T CloneObject<T>(T obj) 
    { 
     if (obj == null) 
      return obj; 
     string ser = JsonConvert.SerializeObject(obj, Formatting.Indented, 
      new JsonSerializerSettings() { 
           NullValueHandling = NullValueHandling.Ignore, 
           MissingMemberHandling = MissingMemberHandling.Ignore, 
           ReferenceLoopHandling = ReferenceLoopHandling.Ignore}); 
     return (T) JsonConvert.DeserializeObject(ser, obj.GetType()); 
    } 

Esempio:

protected object CopyObj(Object obj) 
    { 
     return CloneObject(obj); 
    } 
    var cust1 = this.cts.Customers().Where(cc => cc.Id == 3).Include(cc => cc.Addresses).FirstOrDefault(); 
    var cust2 = CopyObj(cust1) as Customers; 
    //Cust2 now includes copies of the customer record and its addresses 
Problemi correlati