【发布时间】: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