本文介绍了如何通过 protobuf 在 WCF 中避免重复对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小的单元测试来测试循环依赖.

I've a small units tests to test circular dependencies.

我的对象如下:

[ProtoContract]
public class Node
{
    [ProtoMember(1)]
    public String Name { get; set; }

    [ProtoMember(2,AsReference = true)]
    public List<Node> Childs { get; set; }

    public Node()
    {
        Childs = new List<Node>();
    }
}

以及以下服务:

[ServiceContract]
public interface INodeService : IService
{
    [OperationContract]
    Task<Node> GetCyclicNodes();
}

public class NodeService : Service, INodeService
{
    public async Task<int> Add(int a, int b)
    {
        return a + b;
    }

    public async Task<Node> GetCyclicNodes()
    {
        Node nodeA = new Node() {Name = "Node A"};
        Node nodeB = new Node() {Name = "Node B"};
        Node nodeC = new Node() {Name = "Node C"};
        nodeA.Childs.Add(nodeB);
        nodeB.Childs.Add(nodeC);
        nodeC.Childs.Add(nodeA);
        return nodeA;
    }
}

在客户端,我计算对象的数量:

On client side I count the number of objects:

    private int CountNodes(Node node, List<Node> countedNodes = null)
    {
        if (countedNodes == null)
        {
            countedNodes = new List<Node>();
        }
        if (countedNodes.Contains(node))
        {
            return 0;
        }
        else
        {
            countedNodes.Add(node);
            int count = 1;
            foreach (Node nodeChild in node.Childs)
            {
                count += CountNodes(nodeChild, countedNodes);
            }
            return count;
        }
    }

当我调用它时,我希望收到整个层次结构,有 3 个唯一的对象实例(一个用于节点 A"、节点 B"、节点 C").

When I call it, I would expect to receive the whole hierarchy, with 3 unique objects instances(one for "Node A", "Node B", "Node C").

但似乎我有 4 个不同的对象,是对象 A 的两倍.

But it seems that I've 4 differents objects, two times the object A.

由于我的类不是 AsReferenceDefault,我有点担心它看不到它与它得到的对象是同一个对象.

Since my class is not AsReferenceDefault, I'm a little bit afraid that it doesn't see it is the same object than the one it gets.

就我而言,我有一个非常大的商业模型(约 500 个不同的模型),它们都来自同一个根类.每个类都可以在技术上(从模型的角度来看)被另一个类引用,很明显每个类都是一个并且只有一个所有者,而其他类只引用它.这是我可以用 protobuf 做的事情吗?

In my case, I've a very big business model(~500 different models), which all herits from the same root class. Every class can be technically(in a model point of view) referenced by another one, it's always very clear that every class a ONE and ONLY ONE owner, and the other ones are only referring to it.Is this something I can do with protobuf?

因为即使我不知道在使用引用时幕后发生了什么,我有点担心这意味着每个字段都有一个唯一的 ID,即使它们没有被引用

Because even I don't know what is happening behind the scene when using references, I'm a little bit afraid it implies an unique ID is put on EVERY field, even if they are not referenced

编辑

事实上,即使在 ProtoContract 上设置了 AsReferenceDefault = true,我仍然得到 4 个对象而不是 3 个,现在我有点迷失了.

In fact, even while setting the AsReferenceDefault = true on the ProtoContract, I still get 4 objects instead of 3, now I'm a little bit lost.

编辑 2

我确实做了另一个测试,我尝试创建一个 Container 类(我的不同操作现在返回一些 Task>.这个 Container 只包含一个标记为 AsReference = true.现在可以了,我只有 3 个实例.

I did make another test, I tried to have a Container class(my differents operations return now some Task<Container<Node>>. This Container contains only one property which is marked as AsReference = true. Now it works, I've only 3 instances.

但似乎暗示我没有正确理解 AsReference 机制.我在想可能有一个对象的所有者",它没有用 AsReference=true 标记,而所有其他也引用这个对象的将是 AsReference =真的.但如果我理解正确,这会导致有 2 个不同的实例?

But seems to implies that I didn't understood properly the AsReference mechanism. I was thinking it was possible to have one "owner" of the object, which is NOT marked with the AsReference=true, and all the other ones that also reference this object would be AsReference =true. But if I understand properly, this will result in having 2 different instances?

如果是,我不明白设置 AsReference = trueAsReferenceDefault 有什么优势?

If yes, I don't understand the advantage of setting AsReference = true over the AsReferenceDefault?

我理解正确吗?

推荐答案

在我看来,这个问题似乎类似于 这个问题 我们发现根级实体存在问题.

To me it looks as if the question is similar to this question where we realized a problem with the root level entity.

我们还有的是,对于子对象,引用是正确的,但如果根项目再次被引用,反序列化后就会有一个副本.

What we had as well is that for child object the reference where correct but the if the root item was referenced again a copy was there after deserialization.

我们使用了一段时间(然后我们切换到纯 JSON)的解决方法是添加一个额外的根节点.使用这个额外的根节点引用正确反序列化的地方.所以这可能是一个您也可以尝试的变通方法.

Our work-around that we used for some time (and then we switched to pure JSON) was to add an extra root node. With this extra root node references where deseriliazed correctly. So this might be a work-around you could try as well.

这篇关于如何通过 protobuf 在 WCF 中避免重复对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-14 00:04