Poco 父子关系丢失 客户端

发布于 2024-12-18 14:54:13 字数 1061 浏览 7 评论 0原文

我有这样的场景:

STRUCTURE : 
Entity A
 ChildEntity B

Assume this is data in my database 

A1
    (childs)
   B1
   B2
   B3
A2
    (childs)
   B4
   B5
   B6

使用 linq to SQL。我想要一个 B 项目列表 引用父级(A 项目)

服务器端在我的网络服务将数据发送回客户端之前就可以了,

我得到了这样的结构:

B1
  A1
    (childs)
    B1
    B2
    B3
B2
  A1 (parent)
    (childs)
    B1
    B2
    B3
...
...

如果我尝试导航图表,所有项目似乎都在正确的地方。

客户端,在服务器序列化和客户端反序列化之后,我遇到这种情况:

B1
  A1 (parent)
    (childs)    
    B1
    B2
    B3
B2
  NULL
B3
  NULL
B4
  A2 (parent)
    (childs)
    B4
    B5
    B6
B5
  NULL
B6
  NULL

只有 A 项的子项之一保留对父项的引用。我尝试查看客户端和服务器端生成的 XML,但找不到问题。

谁能帮我理解为什么会发生这种情况?
或者有什么建议?

注意:
如果我尝试将列表服务器端压缩为 byte[],并将其解压缩回客户端,将压缩对象转换为 List,则所有项目都会维护客户端关系也正确,一切都好。 序列化/反序列化中的问题

所以我想这是我正在使用的

  • :标准序列化(DataContractSerializer)
  • 标准微软 POCO 模板
  • EF4。

I have this scenario:

STRUCTURE : 
Entity A
 ChildEntity B

Assume this is data in my database 

A1
    (childs)
   B1
   B2
   B3
A2
    (childs)
   B4
   B5
   B6

Using linq to SQL. I want a list of B items
with a reference to parents (A items)

Server side it's all right before my web service send back data to client

I got a structure like this:

B1
  A1
    (childs)
    B1
    B2
    B3
B2
  A1 (parent)
    (childs)
    B1
    B2
    B3
...
...

If I try to navigate the Graph all items seems to be in the right place.

Client side, after server serialization and client deserialization I have this situation:

B1
  A1 (parent)
    (childs)    
    B1
    B2
    B3
B2
  NULL
B3
  NULL
B4
  A2 (parent)
    (childs)
    B4
    B5
    B6
B5
  NULL
B6
  NULL

ONLY one of the childs of A items keeps the reference to the parent. I tried to look at XML generated both client and server side but couldn't find the problem.

Can anyone try to help me understand why this happens?
Or have a suggestion?

NOTE :
If I try to compress the list server side, as byte[], and decompress it back client side, casting the compressed object to List<B>, all items maintain the correct relation also client side, everything is okay. So I imagine it's a problem in Serialization/Deserialization

I'm using:

  • standard serialization (DataContractSerializer)
  • standard microsoft POCO template
  • EF4.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风透绣罗衣 2024-12-25 14:54:13

我发现问题出在哪里:
XMLSerializer 在序列化属性时将它们显然以随机顺序放入 XML 中(也许它遵循从 Datamodel edmx 获得的某些顺序,我没有对此进行调查)
所以我在 XMLSerializer 生成的 XML 中遇到了这种情况:

<b:CHILD_Entity **z:Id="i1"** xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
    <b:CHILD_ID>008acd9a-2074-46b0-b73b-90b8c9123f6f</b:CHILD_ID>
    <b:ReasonInfo>HRC->PLC 11</b:ReasonInfo>
    <b:StartTime>2011-11-29T09:22:36.553</b:StartTime>
    <b:EndTime>2011-11-29T10:31:58.507</b:EndTime>
    <b:Quantity>0</b:Quantity>
    <b:PARENT_Entity z:Id="i2">
        <b:Description i:nil="true"></b:Description>
        <b:UtilizationType>COMMITTED</b:UtilizationType>
        <b:Reason>SETUP</b:Reason>
        <b:ReasonInfo></b:ReasonInfo>
        <b:CHILD_Entities>
            <b:**CHILD_Entity** **z:Ref="i1"**></b:CHILD_Entity>
            <b:**CHILD_Entity** **z:Id="i3"** xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
                <b:CHILD_ID>008acd9a-2074-46b0-b73b-90b8c9123f6f</b:CHILD_ID>
                <b:ReasonInfo>HRC->PLC 11</b:ReasonInfo>
                <b:StartTime>2011-11-29T09:22:36.553</b:StartTime>
                **<b:ProductionCapabilityUtilization z:Ref="i2"></b:ProductionCapabilityUtilization>**
                ***<b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>***
                ..........
            </b:CHILD_Entity>
            ..................

        </b:CHILD_Entities>
        **<b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>**
    </b:PARENT_Entity>
    ***<b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>***
    <b:PROP1>MLM</b:PROP1>
    <b:PROP2>MLM1</b:PROP2>
    <b:Reason>RUN</b:Reason>
</b:CHILD_Entity>
<b:**CHILD_Entity** **z:Ref="i3"** xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"></b:CHILD_Entity>

问题是,有时 FIXUP 生成的代码可能会尝试在设置 PARENT_Entity.PARENT_ID 之前和在 CHILD_Entity.PARENT_Entity SETTER 被触发之后在 CHILD_Entity 上设置 PARENTID。
所以我们遇到了一个奇怪的场景,其中 CHILD_Entity.PARENT 有一个值,但 CHILD_Entity.Parent.PARENT_ID = NULL,因为 DESERIALIZER 仍未处理 XML 中的该属性

要解决此类问题,我必须以这种方式修改 POCO 模板:

  1. 设置计数器变量int propertyPosCounter = 1;

  2. 设置 DataMemberAttribute 时指定 ORDER
    [DataMemberAttribute(Order = <#=propertyPosCounter.ToString()#>)]

  3. propertyPosCounter +=1;

    之后递增计数器

  4. 对每个原始属性重复此过程 - 复杂属性 - 导航属性
    为了让我们在生成的 XML 中始终获得正确的顺序,以使用 POCO 及其 Fixup 概念反序列化客户端大小

在对 POCO.tt 模板进行调整之后,我解决了这些类型的冲突,没有遇到任何问题
正在序列化 ->反序列化从 WCF 服务传递到客户端应用程序的数据结构
XML 序列化的结果是:

<b:CHILD_Entity z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
    <b:CHILD_ID>008acd9a-2074-46b0-b73b-90b8c9123f6f</b:CHILD_ID>
    <b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>
    <b:PROP1>MLM</b:PROP1>
    <b:PROP2>MLM1</b:PROP2>
    <b:Reason>RUN</b:Reason>
    <b:ReasonInfo>HRC->PLC 11</b:ReasonInfo>
    <b:StartTime>2011-11-29T09:22:36.553</b:StartTime>
    <b:EndTime>2011-11-29T10:31:58.507</b:EndTime>
    <b:Quantity>0</b:Quantity>
    <b:PARENT_Entity z:Id="i2">
        <b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>
        <b:Description i:nil="true"></b:Description>
        <b:UtilizationType>COMMITTED</b:UtilizationType>
        <b:Reason>SETUP</b:Reason>
        <b:ReasonInfo></b:ReasonInfo>
        <b:CHILD_Entity>
            <b:CHILD_Entity z:Ref="i1"></b:CHILD_Entity>
            <b:**CHILD_Entity** **z:Id="i3"** xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
                <b:CHILD_ID>008acd9a-2074-46b0-b73b-90b8c9123f6f</b:CHILD_ID>
                ***<b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>***
                <b:ReasonInfo>HRC->PLC 11</b:ReasonInfo>
                <b:StartTime>2011-11-29T09:22:36.553</b:StartTime>
                ..........
                **<b:ProductionCapabilityUtilization z:Ref="i2"></b:ProductionCapabilityUtilization>**
            </b:CHILD_Entity>
        </b:CHILD_Entity>
    </b:PARENT_Entity>
</b:CHILD_Entity>

我试图尽可能清晰,但场景并不简单,所以如果有人需要澄清,请毫不犹豫地询问,我会尽快回答。

希望这篇文章可以帮助其他人:)

问候,
路易吉·马丁内斯·比安奇

I found where the problem was :
The XMLSerializer when serializing properties puts them in the XML apparently in random order (maybe it follows some order it gets from Datamodel edmx, i've not investigated about it)
So i got this scenario in XML generated by the XMLSerializer :

<b:CHILD_Entity **z:Id="i1"** xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
    <b:CHILD_ID>008acd9a-2074-46b0-b73b-90b8c9123f6f</b:CHILD_ID>
    <b:ReasonInfo>HRC->PLC 11</b:ReasonInfo>
    <b:StartTime>2011-11-29T09:22:36.553</b:StartTime>
    <b:EndTime>2011-11-29T10:31:58.507</b:EndTime>
    <b:Quantity>0</b:Quantity>
    <b:PARENT_Entity z:Id="i2">
        <b:Description i:nil="true"></b:Description>
        <b:UtilizationType>COMMITTED</b:UtilizationType>
        <b:Reason>SETUP</b:Reason>
        <b:ReasonInfo></b:ReasonInfo>
        <b:CHILD_Entities>
            <b:**CHILD_Entity** **z:Ref="i1"**></b:CHILD_Entity>
            <b:**CHILD_Entity** **z:Id="i3"** xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
                <b:CHILD_ID>008acd9a-2074-46b0-b73b-90b8c9123f6f</b:CHILD_ID>
                <b:ReasonInfo>HRC->PLC 11</b:ReasonInfo>
                <b:StartTime>2011-11-29T09:22:36.553</b:StartTime>
                **<b:ProductionCapabilityUtilization z:Ref="i2"></b:ProductionCapabilityUtilization>**
                ***<b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>***
                ..........
            </b:CHILD_Entity>
            ..................

        </b:CHILD_Entities>
        **<b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>**
    </b:PARENT_Entity>
    ***<b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>***
    <b:PROP1>MLM</b:PROP1>
    <b:PROP2>MLM1</b:PROP2>
    <b:Reason>RUN</b:Reason>
</b:CHILD_Entity>
<b:**CHILD_Entity** **z:Ref="i3"** xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"></b:CHILD_Entity>

the problem is that could happen that sometimes FIXUP generated code try to set PARENTID on CHILD_Entity before PARENT_Entity.PARENT_ID is set and after CHILD_Entity.PARENT_Entity SETTER was fired.
so we got a strange scenario where CHILD_Entity.PARENT has a value but CHILD_Entity.Parent.PARENT_ID = NULL because the DESERIALIZER has still not processed that property from the XML

To solve this kind of problems i had to modify POCO Template this way :

  1. Set a counter variable int propertyPosCounter = 1;

  2. Specify ORDER when setting DataMemberAttribute
    [DataMemberAttribute(Order = <#=propertyPosCounter.ToString()#>)]

  3. Increment the counter after that propertyPosCounter +=1;

  4. REPEAT This process for each Primitive Properties - Complex Properties - Navigation Properties
    in order we got always the right order in generated XML to Deserialize Client Size using POCO and it's Fixup concept

After this adjustemant to the POCO.tt template i solve those kind of conflicts and got no problems
Serializing -> Deserializing my data structures passed from my WCF service to my client application
the result in the XML serialized is :

<b:CHILD_Entity z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
    <b:CHILD_ID>008acd9a-2074-46b0-b73b-90b8c9123f6f</b:CHILD_ID>
    <b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>
    <b:PROP1>MLM</b:PROP1>
    <b:PROP2>MLM1</b:PROP2>
    <b:Reason>RUN</b:Reason>
    <b:ReasonInfo>HRC->PLC 11</b:ReasonInfo>
    <b:StartTime>2011-11-29T09:22:36.553</b:StartTime>
    <b:EndTime>2011-11-29T10:31:58.507</b:EndTime>
    <b:Quantity>0</b:Quantity>
    <b:PARENT_Entity z:Id="i2">
        <b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>
        <b:Description i:nil="true"></b:Description>
        <b:UtilizationType>COMMITTED</b:UtilizationType>
        <b:Reason>SETUP</b:Reason>
        <b:ReasonInfo></b:ReasonInfo>
        <b:CHILD_Entity>
            <b:CHILD_Entity z:Ref="i1"></b:CHILD_Entity>
            <b:**CHILD_Entity** **z:Id="i3"** xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
                <b:CHILD_ID>008acd9a-2074-46b0-b73b-90b8c9123f6f</b:CHILD_ID>
                ***<b:PARENT_ID>32864280-fe68-4b21-8375-b57ae8bbd7e6</b:PARENT_ID>***
                <b:ReasonInfo>HRC->PLC 11</b:ReasonInfo>
                <b:StartTime>2011-11-29T09:22:36.553</b:StartTime>
                ..........
                **<b:ProductionCapabilityUtilization z:Ref="i2"></b:ProductionCapabilityUtilization>**
            </b:CHILD_Entity>
        </b:CHILD_Entity>
    </b:PARENT_Entity>
</b:CHILD_Entity>

I tried to be as clear as possible but the scenario is not trivial, so if anyone needs clarification do not hesitate to ask for it, i will try to answer as soon as i can.

Hope this post could help someone else :)

Regards,
Luigi Martinez Bianchi

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文