【问题标题】:ADO.NET Entity Data Model serialization issuesADO.NET 实体数据模型序列化问题
【发布时间】:2015-11-23 02:40:54
【问题描述】:

我对这个框架很陌生。我让 VS 从现有数据库中构建数据模型,但在尝试从其 API 2 控制器正确获取数据时遇到问题。

这是模型:

namespace AngularWebApi.Models
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;

    public partial class BlockDeveloper
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage",        "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public BlockDeveloper()
        {
            this.Reviews = new HashSet<Review>();
            this.Topics = new HashSet<Topic>();
        }

        public int DeveloperId { get; set; }
        public string UserName { get; set; }
        public string PassWord { get; set; }
        public string eMail { get; set; }
        int PostCount { get; set; }
        public int RespondCount { get; set; }
        public int Score { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Review> Reviews { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Topic> Topics { get; set; }
    }
}

这是我要执行的 GET:

namespace AngularWebApi.Controllers
{
    public class BlockDevelopersController : ApiController
    {
         private AngularSiteEntities4 db = new AngularSiteEntities4();

        // GET: api/BlockDevelopers
        public IQueryable<BlockDeveloper> GetBlockDevelopers()
        {
            return db.BlockDevelopers;
        }

        //....more actions...
    }
}

我不断收到以下错误:

类型 'System.Data.Entity.DynamicProxies.BlockDeveloper_2BE89EC23AFBD5F46CBA6ED3403E8895016357CD4A3553D07BA526B43E774273' 与数据合同名:预计不会 'BlockDeveloper_2BE89EC23AFBD5F46CBA6ED3403E8895016357CD4A3553D07BA526B43E774273 http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies'。考虑使用 DataContractResolver 或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。

我已经阅读了很多帖子和论坛,并且弹出了两个关键解决方案:使用 [KnownType(typeof(T))] 和 Configuration.ProxyCreationEnabled = false;。

我在我的代码中到处乱扔了 KnownType 属性,但没有运气 - 我完全不知道在自动生成的 ADO.NET 实体数据模型中的何处执行此操作。

我终于尝试了“Configuration.ProxyCreationEnabled = false;”在我的 BlockDevelopersController 中,我不再收到错误消息。我终于可以看到我的 BlockDeveloper 列表了——但是有一个问题,没有任何子对象(评论、主题)被呈现(序列化时它们是空标签)。我知道数据存在,因为如果我调试并单独遍历每个 BlockDeveloper 的评论和主题,我可以看到它。

对于如何获取我的所有数据,我很迷茫。如果我使用“Configuration.ProxyCreationEnabled = false;”,有没有办法得到它?我似乎在读我不能读。如何使用“[KnownType(typeof(T))]”属性来更正此问题(这些属性在 ADO.NET 实体数据模型项目中的确切位置?)。

任何帮助都会很棒,谢谢!

【问题讨论】:

  • 我认为由于模型中的虚拟属性而导致序列化失败。当模型被序列化为 JSON 时,它也会尝试序列化评论和主题的集合,这可能引用了 BlockDeveloper(也许更多?)。您必须确保序列化不会陷入无限循环
  • 我通常将我的实体变成 POCO 类并通过 Web Api 发送这些。
  • @AlexanderDerck - 你是对的,实体模型确实引用了 BlockDeveloper(以及更多),这(如果我理解正确的话)肯定会在序列化过程中导致循环问题。如果可能导致这样的问题,我不确定为什么它们会以这种方式自动设置。我删除了引用,以便每个实体模型与其依赖项具有单向关系。仍然遇到问题......删除标签“虚拟”会删除错误,但根本不会填充子实体。我会继续看的,谢谢你的建议!
  • 如果Review 和Topic 实体不再引用BlockDeveloper,您应该在数据库调用中使用.Include("Review")。那应该加载 blockdeveloper 的子实体
  • @AlexanderDerck - 很好的建议,这让我可以通过 API 完全返回我的 BlockDeveloper 实体!因此,我必须删除创建 AngularSite 模型时创建的不需要的引用(如果错误,我仍然不确定为什么首先创建它们),我必须添加“Configuration.ProxyCreationEnabled = false;”就我的上下文而言,我必须最终将“.Include("Reviews").Include("Topics")" 添加到对数据库的调用中。非常感谢!如果您愿意,我会给您一些时间回复答案,否则我会将其作为答案,以便其他人可以轻松找到,再次感谢。

标签: c# .net entity-framework ado.net asp.net-web-api2


【解决方案1】:

当您尝试将模型中的虚拟属性序列化为 JSON 时,它们会导致无限循环,因为 Review 和 Topic 引用了 BlockDeveloper,反之亦然。您应该使用预加载从包含包含的数据库中获取 Review 和 Topic 模型,而不是尝试延迟加载它们。

【讨论】:

  • 投了赞成票,一旦我的代表达到 15 分,它就会算数,谢谢!
  • 接受答案给出+2
  • 我可以发誓我做到了,对不起。
猜你喜欢
  • 1970-01-01
  • 2013-01-04
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多