简体   繁体   English

使用数据填充分层类结构

[英]Filling a hierarchical class structure with data

I have a hierarchical class structure like this: 我有一个像这样的分层类结构:

Category -> Template -> Instance 类别 - >模板 - >实例

A category contains multiple templates, a template contains multiple instances. 一个类别包含多个模板,一个模板包含多个实例。

If I query the data from the database via a join over all 3 tables, the data looks something like this: 如果我通过所有3个表的连接查询数据库中的数据,则数据如下所示:

CategoryID | CategoryName | CategoryType | TemplateID | TemplateName | TemplateXYZ | InstanceID | InstanceName  
1 | "CatA" | "TypeX" | 1 | "TempA" | "X" | 1 | "InstA" 
1 | "CatA" | "TypeX" | 1 | "TempA" | "X" | 2 | "InstB"
1 | "CatA" | "TypeX" | 1 | "TempA" | "X" | 3 | "InstC"
1 | "CatA" | "TypeX" | 1 | "TempB" | "Y" | 4 | "InstD"

(just an example, the real data tables have a lot more columns) (只是一个例子,真正的数据表有更多的列)

What is the best/common way in C# to fill the classes with this kind of data when cycling through it with a data reader? 在使用数据读取器循环使用此类数据时,C#中最好/最常用的方法是什么?

From the top of my head I would do it this way: 从头到尾我会这样做:

while(data.Read())
{
  // Create new objects each time the ID changes and read the data from the first row
  if(data["CategoryID"] != lastCategoryID) {
    lastCategoryID = data["CategoryID"];
    cat = new Category(data["CategoryName"], data["CategoryType"]);
    catList.Add(cat);
  }
  if(data["TemplateID"] != lastTemplateID) {
    lastTempateID = data["TemplateID"];
    template = new Template(data["TemplateName"], data["TemplateXYZ"]));
    cat.Templates.Add(template);
  }
  template.Instances.Add(new Instance(data["InstanceID"], data["InstanceName"]);
}

Is there a better, more elegant solution to fill the hierarchical class objects? 是否有更好,更优雅的解决方案来填充分层类对象? Maybe using LINQ or Dictionaries? 也许使用LINQ或Dictionaries?

Note: This question is related to my other question about the best way to gather hierarchical data from a DB . 注意:此问题与我关于从数据库收集分层数据最佳方法的其他问题有关。 I split it up because this are two separate issues. 我把它分开是因为这是两个不同的问题。

What you do seems like a good way to work it. 你做什么似乎是一种很好的工作方式。 Just make sure you sort the data in your query by and ID columns you have. 只需确保对查询中的数据和ID列进行排序。 Sort by category then template. 按类别然后按模板排序。 This will ensure you don't go back to one of those IDs and create the object again. 这将确保您不会返回其中一个ID并再次创建对象。

Also - if a template can be in multiple categories, you will have to store each template in a list somewhere to make sure you don't duplicate them over categories. 此外 - 如果模板可以分为多个类别,则必须将每个模板存储在某个列表中,以确保不会在类别上复制它们。

As you read from the data reader, populate an object with the data from each row. 在从数据读取器中读取时,使用每行中的数据填充对象。 At this point don't worry about the duplicates: 此时不要担心重复:

var rawData = new List<Incoming>();
while (data.Read())
{
    rawData.Add( new Incoming(data[0], data[1],data[2],data[3],data[4],data[5],data[6],data[7]));
}

where 哪里

public class Incoming
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public int CategoryType { get; set; }
    public int TemplateID { get; set; }
    public string TemplateName { get; set; }
    public int TemplateXYZ { get; set; }
    public int InstanceID { get; set; }
    public string InstanceName { get; set; }

    public Incoming(int categoryID , string categoryName , int categoryType , int templateId,string templateName ,int templateXYZ , int instanceID , string instanceName    )
    {
        CategoryID =categoryID;
        CategoryName = categoryName; CategoryType = categoryType; TemplateID = templateId;
        TemplateName = templateName; TemplateXYZ = templateXYZ; InstanceID = instanceID; InstanceName = instanceName; 
    }
}

then you can use LINQ to get the individual levels of the hierarchy out: 那么您可以使用LINQ来获取层次结构的各个级别:

var categories = rawData.GroupBy (d => d.CategoryID );

Something like the following would provide you with a direct to class approach: 以下内容将为您提供直接的课程方法:

string[] allLines = File.ReadAllLines("datafile.dat");

var query = from line in allLines
            let data = line.Split('|')
            select Category
                {
                    CategoryID = data[0],
                    CategoryName = data[1],
                    CategoryType = data[2], 
                    Template = new Template { TemplateID = data[3],
                                              TemplateXYZ = data[4],
                                              Instance = new Instance { InstanceID = data[5],
                    InstanceName = data[6] }
                                    }
                };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM