> Code First,Entity Framework 4.3.1;
>用户—-主题,1对多关系;
>具有公共虚拟ICollection的用户<主题> CreatedTopics导航属性(延迟加载);
>具有公共虚拟用户创建者导航属性的主题;
> DataServiceController:DbDataController< DefaultDbContext> ;,Web API beta,ASP.NET MVC 4 Beta,单页应用程序;
> System.Json用于Json序列化;
> Web API操作:
public IQueryable<Topic> GetTopics() { // return DbContext.Topics; // OK return DbContext.Topics.Include("Creator"); //With Exception }
>结果:“w3wp.exe中出现未处理的microsoft .net框架异常”
这里的问题似乎是:我不应该在两个实体中添加导航属性(导致循环引用?),如果我删除用户类中的CreatedTopics导航属性,它将再次正常.
所以,在上面列出的类似上下文中,这是我的问题:
>在1对多关系的情况下如何处理导航属性;
>此外,如果有多对多的关系,我是否必须将其划分为两个1到多个关系;
>使用导航属性的最佳实践和注意事项是什么?
我看过很多相关的帖子,但还不够清楚:(,
谢谢你的帮助!
院长
解决方法
那么你能做什么?您可以告诉序列化程序它应该通过使用DataContract(IsReference = true)标记您的类来跟踪这些循环引用,并使用DataMember属性标记每个传递的属性(查看链接文章以获取如何使用JSON.NET实现它的描述).这将允许序列化器正确识别循环,并且序列化在理论上将成功.理论上因为这也要求不使用延迟加载.否则,您可以序列化比预期更多的数据(在某些灾难性情况下,它可能导致序列化数据库的整个内容).
当您使用延迟加载序列化实体图时,您会对主题及其创建者进行搜索,但序列化也会访问CreatedTopics property =>所有相关主题都是延迟加载和序列化处理,序列化继续访问所有新加载主题的Creator!此过程将继续,直到没有其他对象延迟加载.因此,在序列化实体时不应使用延迟加载.
其他选项是从序列化中排除反向引用.你只需要序列化Creator.您不需要序列化CreatedTopics,因此您可以使用IgnoreDataMember属性(JSONIgnore for JSON.NET)标记该属性.问题是,如果您还使用Web API操作来返回User及其所有CreateTopics,则由于该属性,这将无效.
最后一个选项不使用实体.此选项通常用于Web服务,您可以在其中创建满足特定操作要求的特殊DTO对象,并处理操作中实体和DTO之间的转换(可以借助AutoMapper等工具).
处理一对一,一对多或多对多关系之间没有区别.如果双方都有导航属性,则必须始终处理此问题.