当前位置:  开发笔记 > 编程语言 > 正文

EF4 POCO WCF序列化问题(没有延迟加载,代理/无代理,循环引用等)

如何解决《EF4POCOWCF序列化问题(没有延迟加载,代理/无代理,循环引用等)》经验,为你挑选了0个好方法。

好的,我想确保我的情况和我彻底尝试的一切.我很确定我能做什么,但我还没有找到成功的完美组合.

我正在使用Entity Framework 4 RTM及其POCO支持.我正在寻找一个实体(Config),它包含与另一个实体(App)的多对多关系.我关闭延迟加载禁用上下文的代理创建,并显式加载导航属性(通过.Include()或.LoadProperty()).但是,当加载导航属性(即,为给定的Config加载Apps)时,已加载的App对象已包含对已带入内存的Configs的引用.这会创建一个循环引用.

现在我知道WCF使用的DataContractSerializer可以通过将preserveObjectReferences参数设置为true 来处理循环引用.我已经尝试过这个我在网上发现的几个不同的属性实现.需要防止"对象图包含循环引用且无法序列化"错误.但是,它不会阻止整个图形的序列化,在Config和App之间来回传递.

如果我通过WcfTestClient.exe调用它,我从客户端得到一个stackoverflow(ha!)异常,我就被软管了.我从不同的调用环境得到不同的结果(C#单元测试与Web服务的本地引用似乎工作正常虽然我仍然可以无休止地在Configs和Apps之间来回钻取,但是从coldfusion环境调用它只返回第一个Config列表中的错误和其他错误.)我的主要目标是有一个序列化的图表表示我明确从EF加载(即:配置列表,每个与他们的应用程序,但没有应用程序回到配置导航.)

注意:我还尝试使用ProxyDataContractResolver技术并保持从我的上下文启用代理创建.这会引发抱怨所遇到的未知类型.我读到ProxyDataContractResolver在Beta2中没有完全工作,但应该在RTM中工作.

对于一些参考,这里大致是我如何查询服务中的数据:

var repo = BootStrapper.AppCtx["AppMeta.ConfigRepository"] as IRepository;
repo.DisableLazyLoading();
repo.DisableProxyCreation();

//var temp2 = repo.Include(cfg => cfg.Apps).Where(cfg => cfg.Environment.Equals(environment)).ToArray();
var temp2 = repo.FindAll(cfg => cfg.Environment.Equals(environment)).ToArray();
foreach (var cfg in temp2)
{
    repo.LoadProperty(cfg, c => c.Apps);
}

return temp2;

我认为问题的关键在于从实体框架4加载POCO对象的导航属性时,它预先填充了内存中已有对象的导航属性.尽管已经尽一切努力正确处理循环引用,但这反过来又加强了WCF序列化.

我知道这是很多信息,但它确实阻碍了我们在系统中使用EF4/POCO.我发现有几篇文章和博客涉及这些主题,但对于我的生活,我无法解决这个问题.随意简单地提问并帮助我集体讨论这种情况.

PS:为了彻底,我使用Spring .NET的HEAD版本注入WCF服务,以修复Spring.ServiceModel.Activation.ServiceHostFactory.但是我不认为这是问题的根源.

编辑:如果我没有循环引用,ProxyDataContractResolver类可以正常工作.(即:我将App.Configs的setter设置为私有,这会阻止属性的序列化.)当它通过App对象命中Configs时,它会爆炸 - 它们似乎不会被识别为与顶级配置相同的类型.

EDIT2: EF或WCF似乎无法识别出实体确实相等.即:'Config'与特定的'Config.Apps [x] .Configs [y]'相同.实体键在CSDL中为每个模型正确设置,我已经重写了Equals()函数,以根据实体的"Id"属性来比较实体.这符合症状,因为没有抛出循环引用错误,但它确实是一个循环引用(并炸毁WcfTestClient.exe)并且当它到达'Config.Apps [x] .Configs [y]'级别时,ProxyDataContractResolver会爆炸配置.(它不知道如何映射Config代理.ProxyDataContractResolver也可以工作.它就像它知道如何处理第一轮实体,但第二级它认为是不同的实体.)

哇,我可以罗嗦.对不起人!

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有