2012-10-10 4 views
12

Essayer à nouveau cette question parce que ma première tentative était à peine cohérente: pEntity Framework circulaire Référence

Je suis super confus et en utilisant le code Entity Framework Première

J'ai une classe de forêt.

J'ai une classe Tree.

Chaque forêt peut avoir de nombreux arbres

Quand je tentais de sérialisation je recevais référence circulaire

public class Forest 
{ 

    public Guid ID { get; set; } 
    public virtual List<Tree> Trees { get; set; } 
} 
public class Tree 
{ 
    public Guid ID { get; set; } 
    public Guid? ForestId {get;set;} 

    [ForeignKey("ForestId")] 
    public virtual Forest Forest {get;set;} 
} 

Chaque forêt a des arbres, mais pas tous les arbres est dans une forêt. Je lutte avec soit des erreurs de Multiplicité lorsque vous faites

@(Html.Raw(Json.Encode(Model))) 

Lorsque le modèle est une forêt

et si je fais un ForestIdGuid au lieu d'un Guid? je reçois circulaires erreurs de référence.

J'ai aussi essayé protected override vide

OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Forest>() 
    .HasMany(x => x.Tree) 
    .WithOptional() 
    .HasForeignKey(y => y.ForestId); 
} 

Merci à l'avance

+0

Utilisez-vous DataContractSerializer? Si tel est le cas, vos DataContracts ne s'affichent pas, mais vous devez définir IsReference = true. –

Répondre

16

meilleure approche serait vous devriez utiliser DTO pour transférer uniquement les données que vous voulez le client. Les DTO devraient avoir juste des propriétés simples afin qu'il ne crée pas une erreur de référence circulaire. À l'heure actuelle, la forêt a List<Trees> Trees et chaque Tree dans les arbres a Forest et que Forest nouveau a List<Trees>

Ou

Vous pouvez décorer vos attributs avec ScriptIgnore pour les propriétés que vous ne voulez pas le JSON. Encodez pour sérialiser, puis cela ne sera pas renvoyé au client.

http://msdn.microsoft.com/en-us/library/system.web.script.serialization.scriptignoreattribute.aspx

Par exemple:

public class Forest 
{  
    public Guid ID { get; set; } 
    public virtual List<Tree> Trees { get; set; } 
} 
public class Tree 
{ 
    public Guid ID { get; set; } 
    public Guid? ForestId {get;set;} 

    [ForeignKey("ForestId")] 
    [ScriptIgnore] 
    public virtual Forest Forest {get;set;} 
} 

Edit:

Avec ScriptIgnore vous devez également supprimer virtual de Forest et Trees et cela pourrait fonctionner. Je l'ai testé. Cependant, je ne conseillerais pas cela parce que le mot-clé virtuel est ce que le chargement paresseux. Par conséquent, comme je l'ai dit, vous devez créer des DTO basés sur ces modèles et envoyer uniquement des DTO au client.

+0

Même avec Script ignore, il m'a donné une référence circulaire, donc j'ai regardé le modèle. Le champ ID de l'arborescence continue de forer, tout comme le champ ID de la forêt. J'utilise des GUID générés dans la base de données en utilisant NewId() cela peut-il causer mon problème? J'ai même mis Trees = null dans Forest et il donne toujours une référence circulaire. – Jordan

+0

@Jordan: voir mon édition. – TCM

+0

Merci beaucoup. J'ai fini par me rendre compte hier soir que je pouvais enlever le virtuel. Je me rends compte que ce n'est pas la solution idéale, mais je suis juste prototypage pour ce projet, donc dans ce cas, c'est bien. Dans les futurs travaux de production j'utiliserai en effet des DTO! Merci beaucoup! – Jordan

Questions connexes