实体框架循环参考

时间:2012-10-10 04:32:17

标签: c# entity-framework code-first

再次尝试这个问题,因为我的第一次尝试几乎没有连贯性:p

所以我非常困惑并使用Entity Framework Code First

我有一个Forest类。

我有一个Tree类。

每个森林可以有很多树

当我尝试序列化时,我正在获得循环引用

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;}
 }

每片森林都有树木,但不是每棵树都在森林里。在做

时,我遇到了Multiplicity的错误
@(Html.Raw(Json.Encode(Model)))

模型是森林

如果我ForestId Guid而不是Guid?,我会收到循环参考错误。

我也试过了 protected override void

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

提前致谢

1 个答案:

答案 0 :(得分:16)

最佳方法是您应该使用DTO仅将您想要的数据传输到客户端。 DTO应该只具有简单的属性,因此不会产生循环引用错误。目前,林有List<Trees> Trees,树中的每个Tree都有Forest,而Forest又有List<Trees>

您可以使用ScriptIgnore为您不想要的属性修饰属性 Json.Encode序列化然后不会被发送回客户端。

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

例如:

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;}
 }

修改

除了ScriptIgnore之外,您还应该从virtualForest移除Trees,这样可行。我测试过了。但是,我不建议,因为虚拟关键字是懒惰加载。因此,正如我所说,您需要根据这些模型创建DTO,并仅将DTO发送给客户。