gpt4 book ai didi

asp.net-mvc-3 - 使用 JSON.Net 序列化 EF4.1 实体

转载 作者:行者123 更新时间:2023-12-04 15:47:47 24 4
gpt4 key购买 nike

我正在使用 MVC3、Razor View 引擎、带有工作单元的存储库模式以及使用 EF4.1 Code First 来定义我的数据模型来构建应用程序。

这里有一点背景(如果你愿意,可以涂上光泽)。

应用程序本身只是一个 Intranet '菜单'。

两个主要实体是 MenuItem 和 Department ,其中:

  • MenuItem 可以有多个部门
  • 部门可以有很多菜单项
  • MenuItem 可能有一个 MenuItem 作为父级

  • 这就是我定义我的实体的方式
    public class MenuItem
    {
    public int MenuItemId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public virtual ICollection<Department> Departments { get; set; }
    public int? ParentId { get; set; }
    public virtual MenuItem ParentMenuItem { get; set; }
    }

    public class Department
    {
    public int DepartmentId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<MenuItem> MenuItems { get; set; }
    }

    我正在使用 FluentAPI 为 MenuItem 定义自引用多对多。

    我遇到的问题是通过 JSON 将 MenuItem 传递给 View 。
    核心问题是我的实体之间有一个内置 JSON 解析器无法处理的循环引用,并且我仍然启用了延迟加载和代理生成。

    我使用来自 Nuget 的 JSON.net 库作为我的 JSON 序列化程序,因为这似乎是解决循环引用问题的好方法。我现在不确定如何“修复”代理生成问题。目前,序列化程序抛出 The RelationshipManager object could not be serialized. This type of object cannot be serialized when the RelationshipManager belongs to an entity object that does not implement IEntityWithRelationships.
    谁能帮我这个?如果我关闭代理生成,我将有一段时间加载所有 MenuItem 子项,所以我很想保持这个状态。我已经阅读了相当多的内容,并且似乎有各种不同的答案,包括将实体投影到另一个对象中并对其进行序列化等等。理想情况下,有某种方法可以配置 JSON.net 以忽略 RelationshipManager 对象?

    更新

    这是我用作 JSON.Net 序列化程序的自定义 ContractResolver 的内容。这似乎解决了我的问题。
    public class ContractResolver : DefaultContractResolver
    {
    private static readonly IEnumerable<Type> Types = GetEntityTypes();
    private static IEnumerable<Type> GetEntityTypes()
    {
    var assembly = Assembly.GetAssembly(typeof (IEntity));
    var types = assembly.GetTypes().Where(t => String.Equals(t.Namespace, "Namespace", StringComparison.Ordinal));
    return types;
    }

    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
    if (!AllowType(objectType))
    return new List<MemberInfo>();

    var members = base.GetSerializableMembers(objectType);
    members.RemoveAll(memberInfo => (IsMemberEntityWrapper(memberInfo)));
    return members;
    }

    private static bool AllowType(Type objectType)
    {
    return Types.Contains(objectType) || Types.Contains(objectType.BaseType);
    }

    private static bool IsMemberEntityWrapper(MemberInfo memberInfo)
    {
    return memberInfo.Name == "_entityWrapper";
    }
    }
    IEntity是我的所有 Code First 实体对象都实现的接口(interface)。

    最佳答案

    我意识到这个问题有一个公认的答案,但我想我会为 future 的观众发布我的 EF Code First 解决方案。我能够使用下面的契约(Contract)解析器绕过错误消息:

     class ContractResolver : DefaultContractResolver
    {
    protected override List<System.Reflection.MemberInfo> GetSerializableMembers(Type objectType)
    {
    if (objectType.Namespace.StartsWith("System.Data.Entity.Dynamic"))
    {
    return base.GetSerializableMembers(objectType.BaseType);
    }

    return base.GetSerializableMembers(objectType);
    }
    }

    这是有效的,因为 EF Code First 类继承自您实际想要序列化的 POCO 类,因此如果我们能够识别何时查看 EF 生成的类(通过检查命名空间),我们就可以使用基础中的属性进行序列化类,因此只序列化我们一开始真正追求的 POCO 属性。

    关于asp.net-mvc-3 - 使用 JSON.Net 序列化 EF4.1 实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6991596/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com