WCF 和嵌套数据协定

Posted

技术标签:

【中文标题】WCF 和嵌套数据协定【英文标题】:WCF and nested Data Contracts 【发布时间】:2013-01-29 17:26:21 【问题描述】:

对 WCF 来说是全新的。真的可以使用一些帮助。

我有一个包含 (100) 个对象的列表,其中包含 4 个数据成员。 DM1、DM2、DM3、DM4

我有一堆数据合同

DC1
 List<DC2>

DC2
 <DM1 Value=n> (n could be any number below 5, so there could be up to 5 DC2 inside the List in DC1)
 List<DC3>

DC3
 <DM2 value=n> (n could be any number below 10, so up to 10 DC3 inside the List in DC2)
 List<DC4>

DC4
 <DM3>
 <DM4>

需要遍历原始对象列表,并根据原始对象列表的数据成员中的不同值,使用各种嵌套数据合约创建一个数据合约 (DC1)。

例如:

<DC1>
  <DC2>
    <DM1 value = "a">
    <DC3>
      <DM2 value = 1>
      <DC4>
        <DM3>
        <DM4>
      <DM2 value = 2>
      <DC4>
        <DM3>
        <DM4>
      <DC4>
        <DM3>
        <DM4>
    </D3>
  </DC2>
  <DC2>
    <DM1 value = "b">
    <DC3>
      <DM2 value = 1>
      <DC4>
        <DM3>
        <DM4>
      <DM2 value = 2>
      <DC4>
        <DM3>
        <DM4>
      <DC4>
        <DM3>
        <DM4>
    </D3>
  </DC2>
<DC1>

最好的方法是什么?

谢谢!

这是 DataContracts 以及使用 DC1 传递信息的服务合同:

[DataContract]
public class DC1

    [DataMember]
    public string string  get; set; 

    [DataMember]
    public List<DC2> LDC2 get; set; 

[数据合约] 公共课 DC2 [数据成员] 公共字符串类型获取;放;

    [DataMember]
    public List<DC3> DC3s get; set; 

[数据合约] 公共课 DC3 [数据成员] 公共十进制数 得到;放;

    [DataMember]
    public List<DC4> DC4s get; set; 

[数据合约] 公共课 DC4 [数据成员] 公共 int num2 得到;放;

    [DataMember]
    public decimal Valget; set;

服务合同: [ServiceContract(Namespace = Constants.Namespace)] 公共类服务

    [OperationContract]
    DC1 GetMethod(int num);

数据集:

是以下对象的 LIST:

[Serializable]
public class Data

    public string Type  get; set; 
    public double Num  get; set; 
    public double Num2 get; set; 
    public decimal Val get; set; 


此列表中可以包含 100 个(或更多)这些对象。 最多5种,Num最多10种,Num2最多5种。

感谢您的回复,并希望澄清!

【问题讨论】:

你能解释一下你想要完成的事情吗?甚至可能是您当前类的一些代码,以及您如何使用 [DataContract] 和 [DataMember] 属性装饰它们。因为如果您有一个将 DC1 类定义为输入或输出的 [OperationContract] 方法,那么您所问的似乎 WCF 已经隐式执行了。 感谢您的回复。为了清楚起见,用更多代码编辑了问题! 【参考方案1】:

可能有比让 LINQ 完成所有工作更有效的方法。但是,这似乎是一个关于如何将非规范化数据转换为规范化对象的问题,因此 GroupBy 作为一种易于编码的解决方案跳出来了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace WcfTestService

    [ServiceContract]
    public interface ISoapService
    
        [OperationContract]
        DC1 GetDC1();
    

    public class SoapService : ISoapService
    
        public DC1 GetDC1()
        
            // Example dataset
            var dataset = new List<Data>()
            
                new Data()  Type = "a", Num = 1, Num2 = 1, Val = 41.00m ,
                new Data()  Type = "a", Num = 2, Num2 = 1, Val = 42.00m ,
                new Data()  Type = "a", Num = 2, Num2 = 2, Val = 43.00m ,
                new Data()  Type = "b", Num = 1, Num2 = 1, Val = 44.00m ,
                new Data()  Type = "b", Num = 2, Num2 = 1, Val = 45.00m ,
                new Data()  Type = "b", Num = 2, Num2 = 2, Val = 46.00m ,
            ;

            // Process dataset into data contract objects
            return new DC1()
            
                DC2s = dataset.GroupBy(x => x.Type).Select(typeGrouping => new DC2()
                
                    DM1 = typeGrouping.Key,
                    DC3s = typeGrouping.GroupBy(x => x.Num).Select(numGrouping => new DC3()
                    
                        DM2 = Convert.ToDecimal(numGrouping.Key),
                        DC4s = numGrouping.Select(x => new DC4()
                        
                            DM3 = Convert.ToInt32(x.Num2),
                            DM4 = x.Val
                        ).OrderBy(x => x.DM3).ToList()
                    ).OrderBy(x => x.DM2).ToList()
                ).OrderBy(x => x.DM1).ToList()
            ;
        
    

    [Serializable]
    public class Data
    
        public string Type  get; set; 
        public double Num  get; set; 
        public double Num2  get; set; 
        public decimal Val  get; set; 
    

    [DataContract]
    public class DC1
    
        [DataMember]
        public List<DC2> DC2s  get; set; 
    

    [DataContract]
    public class DC2
    
        [DataMember]
        public string DM1  get; set; 
        [DataMember]
        public List<DC3> DC3s  get; set; 
    

    [DataContract]
    public class DC3
    
        [DataMember]
        public decimal DM2  get; set; 
        [DataMember]
        public List<DC4> DC4s  get; set; 
    

    [DataContract]
    public class DC4
    
        [DataMember]
        public int DM3  get; set; 
        [DataMember]
        public decimal DM4  get; set; 
    

GetDC1() 的输出应该非常接近您的示例输出,但都是 WCF'ified。

【讨论】:

感谢 Sybeus 的迅速而彻底的回复。这就像一个魅力,只需极少的修改。

以上是关于WCF 和嵌套数据协定的主要内容,如果未能解决你的问题,请参考以下文章

引用相同数据协定的多个 WCF 服务

避免在 WCF 数据协定中填充扩展属性

通过 WCF 调用传递继承的“数据协定”?

无法从启用 wcf json 的服务向客户端返回嵌套类型

哪种列表/集合类型最适合在 WCF 数据协定中使用?

使用来自外部程序集的类的 WCF 数据协定