简体   繁体   English

WCF 错误序列化周期参考

[英]WCF error serializing cycle reference

I'm trying to return lists of objects that have references to another objects and viceversa.我正在尝试返回引用另一个对象的对象列表,反之亦然。

I only want the lazy load to get the "first level children", I mean, if I have a "Person" object with a "Place" property, I want the place data to be loaded but not every object in "Place" object needs to be loaded... because this would ahead to a cyclic reference...我只希望延迟加载来获得“第一级孩子”,我的意思是,如果我有一个带有“Place”属性的“Person”object,我希望加载地点数据,但不是“Place”中的每个 object ZA8CFDE63311BD59EB2AC966F8需要加载...因为这将提前到循环引用...

I've read that I could do this by using [DataContract(IsReference = true)] on every Object.我读过我可以通过在每个 Object 上使用 [DataContract(IsReference = true)] 来做到这一点。

I've set every object in the model (auto-generated by EF) with that decoration but it's still failing when trying to send it back to the service caller.我已经在 model(由 EF 自动生成)中设置了每个 object 的装饰,但是在尝试将其发送回服务调用者时仍然失败。

Am I missing anything?我错过了什么吗? Thanks in advance.提前致谢。

I have used the [DataContract(IsReference=true)] successfully to solve the cyclic dependency issue in the past.我过去曾成功使用[DataContract(IsReference=true)]解决循环依赖问题。 Admittedly they were not objects generated by EF, but I' not sure how much that should matter.诚然,它们不是 EF 生成的对象,但我不确定这有多重要。

What is the exact error?确切的错误是什么?

Is it that the graph is getting to big?是不是图变大了?

Could it be that your objects are not the same instances, but different instances of the conceptually same type?难道你的对象不是相同的实例,而是概念上相同类型的不同实例?

So when your TypeA-instance1 gets serialized and it has a reference to TypeB-instance1 which has a Reference to TypeA-instance1 the 2 actual TypeA-instance1 objects to not compare equal so the serializer does not attempt to reuse the references?因此,当您的 TypeA-instance1 被序列化并且它具有对 TypeB-instance1 的引用时,该引用具有对 TypeA-instance1 的引用,两个实际的 TypeA-instance1 对象不比较相等,因此序列化程序不会尝试重用引用?

You could override the equals method on your objects and do some equality testing based on properties of your object rather than the default memory address that will be used.您可以覆盖对象上的 equals 方法,并根据 object 的属性而不是将使用的默认 memory 地址进行一些相等性测试。

I mean, if I have a "Person" object with a "Place" property, I want the place data to be loaded but not every object in "Place" object needs to be loaded...我的意思是,如果我有一个带有“Place”属性的“Person”object,我希望加载地点数据,但不是“Place”中的每个 object 都需要加载...

That is not possible when using lazy loading.使用延迟加载时这是不可能的。 Once the entity gets serialized the serializer will access every single property.一旦实体被序列化,序列化程序将访问每个属性。 Accessing every navigation property will trigger lazy loading and serializer will continue with loaded properties => it will always serialize complete object graph.访问每个导航属性将触发延迟加载,并且序列化程序将继续加载属性=>它将始终序列化完整的 object 图。 In your scenario it can mean:在您的情况下,这可能意味着:

  1. Serializer will start with a Person which have navigation property to Place序列化程序将从具有导航属性到PlacePerson开始
  2. Lazy loading will load the Place and serializer will serialize.延迟加载将加载Place并且序列化程序将序列化。
  3. If the Place have navigation property to all Persons lazy loading will trigger and load all persons referencing the Place !如果Place具有所有Persons的导航属性,则延迟加载将触发并加载引用Place的所有人员!
  4. Serializer will start serializing every single loaded Person - if IsReference is set to false you will get exception with cycles in object graph.序列化程序将开始序列化每个加载的Person - 如果IsReference设置为false ,您将在 object 图中出现循环异常。 If not it will create huge message.如果不是,它将产生巨大的信息。

That is very basic explanation what happens if you try to serialize object when using lazy loading.这是非常基本的解释,如果您在使用延迟加载时尝试序列化 object 会发生什么。 If your entities have other navigation properties the same effect will happen for them.如果您的实体具有其他导航属性,则会对它们产生相同的效果。 In the worst case you can easily build an operation which will try to pull and serialize all data from the database.在最坏的情况下,您可以轻松构建一个操作,该操作将尝试从数据库中提取和序列化所有数据。 That will most probably lead to timeout.这很可能会导致超时。

There is one more problem with lazy loading.延迟加载还有一个问题。 Serialization takes place outside of operation scope.序列化发生在 scope 操作之外。 So if you close / dispose ObjectContext in the operation you will get an exception when entity triggers lazy loading.因此,如果您在操作中关闭/处置ObjectContext ,当实体触发延迟加载时,您将收到异常。

Don't use lazy loading when exposing entities on WCF or use DTO to control what data should be passed from the operation.在 WCF 上公开实体时不要使用延迟加载,或者使用 DTO 来控制应该从操作中传递哪些数据。

You may want to convert your object tree to other, flat objects and return those instead.您可能希望将 object 树转换为其他平面对象并返回这些对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM