在实体框架中获取循环引用错误

时间:2014-03-01 21:04:45

标签: c# entity-framework

我收到如下错误:

'Object graph for type 'System.Collections.Generic.HashSet`1[[ERP_Lite_Data.
MenuItem, ERP_Lite_Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' 
contains cycles and cannot be serialized if reference tracking is disabled.

我的数据库中有一个名为MenuItems的表。 MenuItems中的字段和关系显示在下图中:

enter image description here

实体框架生成的此表的类如下:

public partial class MenuItem
{
    public MenuItem()
    {
        this.MenuItems1 = new HashSet<MenuItem>();
    }

    public int MenuItemID { get; set; }
    public string Title { get; set; }
    public Nullable<int> ParentID { get; set; }

    public virtual ICollection<MenuItem> MenuItems1 { get; set; }
    public virtual MenuItem MenuItem1 { get; set; }
}

我在互联网上搜索了上述错误,无处不在我得到了将DataMember属性应用于类成员的相同解决方案。所以我已经这样做了。这是修改后的MenuItem.cs。

[DataContract]    
public partial class MenuItem
{
    public MenuItem()
    {
        this.MenuItems1 = new HashSet<MenuItem>();
    }

    [DataMember, Key]
    public int MenuItemID { get; set; }

    [DataMember]
    public string Title { get; set; }

    [DataMember]
    public Nullable<int> ParentID { get; set; }

    [DataMember]
    public virtual ICollection<MenuItem> MenuItems1 { get; set; }

    [DataMember]
    public virtual MenuItem MenuItem1 { get; set; }
}

但我仍然得到同样的错误。有人可以建议我一些解决方法吗?

更新

如果我使用以下方法返回所有菜单项,它可以正常工作:

public IEnumerable<MenuItem> GetAllMenuItems()
{
    using (Entities db = new Entities())
    {
        return (from m in db.MenuItems
                select m).ToList();
    }
}

我将其改为以下内容的那一刻:

public IEnumerable<MenuItem> GetAllMenuItems()
{
    using (Entities db = new Entities())
    {
        return (from m in db.MenuItems
                select new MenuItem
                {
                    MenuItemID = m.MenuItemID,
                    Title = m.Title,
                    ParentID = m.ParentID
                }).ToList();
    }
}

我收到另一个错误:

The entity or complex type 'Models.MenuItem' cannot be constructed in a LINQ to Entities query.

你可以让我写下面的代码:

return (from m in db.MenuItems
        select new 
        {
            MenuItemID = m.MenuItemID,
            Title = m.Title,
            ParentID = m.ParentID
        }).ToList();

那么我的方法的返回类型应该是什么?

1 个答案:

答案 0 :(得分:2)

最引人注目的问题是串行化。将projection用于某些没有此类引用的类型,并避免异常。

换句话说,只需从EF模型中选择所需的属性,不要添加嵌套复杂类型的字段,这些字段也具有指向同一对象的属性,从而创建循环引用。