在实体框架代码使用导航属性第一(Using navigation properties in ent

2019-09-19 01:32发布

语境:

  • 代码首先,实体框架4.3.1;
  • 用户----主题,1对多的关系;
  • Userpublic virtual ICollection<Topic> CreatedTopics导航属性(延迟加载);
  • Topicpublic virtual User Creator导航属性;
  • DataServiceController : DbDataController<DefaultDbContext>网络API的β,ASP.NET MVC 4贝塔,单页的应用;
  • System.Json的JSON序列化;
  • 网页API操作:

     public IQueryable<Topic> GetTopics() { // return DbContext.Topics; // OK return DbContext.Topics.Include("Creator"); //With Exception } 
  • 结果:“发生在w3wp.exe的未处理的Microsoft .NET框架例外”

这里的问题似乎是:我不应该在两个实体 (?原因循环引用), 添加导航属性 ,如果我删除CreatedTopics在导航属性User级,这将再次确定。

因此, 在相似背景像上面列出的 ,这里是我的问题:

  1. 如何处理在1到许多关系的情况导航属性;
  2. 更进一步,怎么样一个多对多的关系,我一定把它分为两个1对多的关系;
  3. 什么是最佳做法和使用导航属性的注意事项?

我看了很多相关的帖子,但还是不够清楚:(,

谢谢你的帮助!

院长

Answer 1:

这不是第一次代码或EF一个问题 - 这是序列化的问题。 只需使用你的对象图转换为一定的代表性在Web API消息传递的串行无法与默认循环引用的工作。 根据您要使用的Web API的报文格式,默认情况下使用不同的串行- 这里更多的是通过网络API以及如何去改变它方式使用默认序列化。 下面的文本假设您正在使用DataContractJsonSerializerDataContractSerializer (应该是XML序列化的默认值),但同样是可能的JSON.NET(应该是默认JSON序列- JSON序列化可以切换到DataContractJsonSerializer但默认的序列比较好) 。

所以,你可以做什么? 你可以告诉它应该与标记你的类跟踪这些循环引用串行DataContract(IsReference = true)并与每个通过的财产DataMember属性(检查是否有说明如何与JSON.NET实现它链接的文章)。 这将允许串行正确认识循环和序列化将在理论上获得成功。 从理论上讲,因为这也要求不使用延迟加载。 否则,你可以序列化更多的数据比你预期的(在某些情况下灾难性它可能会导致序列化数据库的全部内容)。

当你用序列化延迟加载实体图形使您serailze一个Topic和它Creator ,但系列化还将访问CreatedTopics属性=>所有相关主题是懒惰的加载和序列化和系列化加工继续参观Creator的所有新加载的主题! 这个过程一直持续,直到没有其他对象延迟加载。 正因为如此序列化实体时,你不应该使用延迟加载。

另一种选择是排除从后面系列化参考。 你只需要序列化Creator 。 你并不需要序列CreatedTopics所以你可以标记与属性IgnoreDataMember属性( JsonIgnore为JSON.NET)。 问题是,如果你也有网页API行动返回User用他所有的CreateTopics这不会因为属性的工作。

最后一个选项是不使用的实体。 在其中创建特殊的DTO对象进行具体操作满足要求,你处理里面的操作实体和DTO的之间的转换(可能与像AutoMapper一些工具帮助)此选项通常在Web服务中使用。

有处理一个对一个,一个一对多或多对多的关系很多没有区别。 如果你有两面导航属性,必须始终处理这个问题。



文章来源: Using navigation properties in entity framework code first