开发者

WCF error serializing cycle reference

开发者 https://www.devze.com 2023-03-11 07:05 出处:网络
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

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...

I've read that I could do this by using [DataContract(IsReference = true)] on every Obj开发者_开发百科ect.

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.

Am I missing anything? Thanks in advance.


I have used the [DataContract(IsReference=true)] successfully to solve the cyclic dependency issue in the past. Admittedly they were not objects generated by EF, but I' not sure how much that should matter.

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?

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.


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...

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. In your scenario it can mean:

  1. Serializer will start with a Person which have navigation property to Place
  2. Lazy loading will load the Place and serializer will serialize.
  3. If the Place have navigation property to all Persons lazy loading will trigger and load all persons referencing the 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. If not it will create huge message.

That is very basic explanation what happens if you try to serialize object when using lazy loading. 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. So if you close / dispose ObjectContext in the operation you will get an exception when entity triggers lazy loading.

Don't use lazy loading when exposing entities on WCF or use DTO to control what data should be passed from the operation.


You may want to convert your object tree to other, flat objects and return those instead.

0

精彩评论

暂无评论...
验证码 换一张
取 消