如何将数据向下一级添加到IEnumerable类型?

时间:2019-07-17 06:32:15

标签: c# .net confluent-kafka

我正在从事.Net项目。我的产品型号如下。

class Product
{
public IEnumerable<OptionData> Options { get; set; }
}

然后我在下面有OptionData模型。

public class OptionData
  {
    public Colour PrimaryColour { get; set; }

    public Colour SecondaryColour { get; set; }

    public IEnumerable<SizeData> Sizes { get; set; }
  }

然后我在下面有SizeData模型。

public class SizeData
  {
    public string KeycodeNumber { get; set; }

    public Size Size { get; set; }
  }

然后我的尺寸模型在下面。

public class Size
  {
    public string Name { get; set; }
  }

然后,我正在使用这些模型将数据发送到某些邮件系统。就我而言,这是融合的卡夫卡。

Options = new Option[]
            {
              new Option
              {
                PrimaryColour = new CodeNamePair
                {
                  Name = "White",
                },
                SecondaryColour = new CodeNamePair
                {
                  Name = "red",
                },
                Sizes = new SizeElement[]
                {
                  new SizeElement
                  {
                    Size = new KafkaProductEvent.Size
                    {
                      Name = "10"
                    },
                    KeycodeNumber = 232
                  }
                }
              }
            }

然后通过消费者我正在提取数据。我能够获得以下PrimaryColour或SecondaryColour。

IEnumerable<object> options = (IEnumerable<object>)((GenericRecord)response.Message.Value["Product"])["Options"];
      foreach (var data in options)
      {
        OptionData optionData = new OptionData()
        {
          PrimaryColour = new Colour()
          {
            Name = (string)((GenericRecord)((GenericRecord)data)["PrimaryColour"])["Name"],
          },
          SecondaryColour = new Colour()
          {
            Name = (string)((GenericRecord)((GenericRecord)data)["SecondaryColour"])["Name"]
          }
        };
      }

然后我也想获取Sizes数据。我尝试过这样的事情。

Sizes = new SizeData[]
          {
            new SizeData()
            {
              Size = new ProductEvents.Size()
              {
                Name = "";
              }
            }
          }

我不确定如何从上方获取尺寸名称。有人可以帮我找出来。任何帮助,将不胜感激。谢谢

1 个答案:

答案 0 :(得分:1)

我在您发布的代码中看到的主要挑战是客户端适配器公开的那种API,您要使用它们来对具有多个聚合对象的复杂数据模型进行反序列化,挑战您的工作是,将其中的每个记录类型转换将每个层次结构转换为GenericRecord,然后将其类型转换为实际的.Net类型对象,这意味着随着聚合层次结构的增长,反序列化实际对象将变得极为复杂,尤其是对于聚合集合:

还有与Options反序列化有关的一点:

class Product
{
  public IEnumerable<OptionData> Options { get; set; }
}

您的代码是:

IEnumerable<object> options = (IEnumerable<object>)((GenericRecord)response.Message.Value["Product"])["Options"];

我想知道的是为什么您不能将强制类型转换为IEnumerable<OptionData>,让它变得简单一点,让我们假设如果不可能,那么在列举IEnumerable<object> options时为什么仍然不能强制转换为OptionData对象的类型,使用的适配器或方法面临的挑战是,它需要完整的对象和层次结构/属性名称才能反序列化,理想情况下,一旦您填充了{{1 }}在这种情况下,其余所有都将以递归方式填写,一个很好的例子是Product,它将自动填充任何复杂性的对象,将使任何不可用的内容成为null /默认值,并且需要最少的反序列化代码。

实际上,您可以做的是,开发自己的适配器,该适配器通过反射读取属性详细信息并填充输入中可用的数据或将其丢弃。就目前而言,这就是您拥有的所有API,然后应采用以下方法:

Newtonsoft Json
  

有什么区别?

  1. 您正在尝试使用对象初始化程序来填充IEnumerable<object> options = (IEnumerable<object>)((GenericRecord)response.Message.Value["Product"])["Options"]; foreach (var data in options) { OptionData optionData = new OptionData() { PrimaryColour = new Colour() { Name = (string)((GenericRecord)((GenericRecord)data)["PrimaryColour"])["Name"], }, SecondaryColour = new Colour() { Name = (string)((GenericRecord)((GenericRecord)data)["SecondaryColour"])["Name"] }, Sizes = new List<SizeData>() // Initialize Collection Here }; IEnumerable<object> SizesEnumerable = (IEnumerable<object>)(((GenericRecord)data)["Sizes"]); foreach (var size in SizesEnumerable) { var sizeValue = new SizeData { KeycodeNumber = (string)((GenericRecord)size)["KeycodeNumber"], Size = new Size { Name = (string)((GenericRecord)((GenericRecord)size)["Size"])["Name"] } }; ((List<SizeData>)optionData.Sizes).Add(sizeValue); // Add Data here } } 来填充集合,但这并没有提供根据您的情况进行进一步处理的选项
  2. 还请注意,我将IEnumerable<SizeData> Sizes设为IEnumerable<SizeData> Sizes,因为我们无法使用对象初始化程序,因此我们无法使用数组,因为我们事先不知道大小
  3. Going使用与您相同的逻辑来填充数据