2010-12-30 17 views
5

と階層クラス構造を充填:私はこのような階層的なクラス構造を有するデータ

カテゴリ - >テンプレート - >インスタンス

カテゴリには、複数のテンプレートが含まれているが、テンプレートは複数のインスタンスが含まれています。私はすべての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" 

(単なる一例を、実際のデータテーブルは、より多くの列を持っている)

データリーダーでこの種のデータを循環させるときに、C#でこの種のデータをクラスに入力する最も一般的な方法は何ですか?私はこのようにそれを行うだろう、私の頭の上から

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"]); 
} 

は、階層的なクラスオブジェクトを埋めるために、より良い、よりエレガントな解決策はありますか?たぶんLINQまたは辞書を使用していますか?

注:この質問は、best way to gather hierarchical data from a DBに関する私の他の質問に関連しています。これは2つの別々の問題であるため、分割しました。

答えて

3

あなたはそれをうまくやっているようです。ちょうどあなたが持っているIDカラムとあなたのクエリのデータを並べ替えることを確認してください。カテゴリ別に並べ替え、テンプレート。これにより、これらのIDのいずれかに戻り、オブジェクトを再度作成しないようにします。

また、テンプレートが複数のカテゴリに含まれる場合は、各テンプレートをリストのどこかに格納して、カテゴリに重複させないようにする必要があります。次のような

+0

感謝をそれを指摘するために、テンプレートは実際には複数のカテゴリに入ることができます。私はまだ何とか最初のものだけから多くの行に等しいデータを得ることに不満を抱いていますが、良い方法はありません。 – magnattic

-1

何かが、クラスのアプローチへの直接をご提供します:

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] } 
            } 
       }; 
+3

違反はありませんが、あなたはその質問を読んだことがありますか?私はデータベースからデータを照会し、あなたの答えは階層的なデータ構造とは関係がありません。 – magnattic

+0

はい私はそれを読んだので、私はあなたの構造をとり、それをオブジェクトに入れるソリューションをあなたに与えました。あなたのCategoriesオブジェクトとは対照的に、私は新しいものを入れました。私は、テンプレートとインスタンスオブジェクトをインラインでインスタンス化できることを知っていると思っていました。 – phillip

+0

これで、転記が階層内で表示されるように更新されました。通常、私はこの種のコードを書くときに、このようにすべてをインラインで入れません - 私は通常それらを個別に作成し、その子オブジェクトを親にまとめますが、これは単なる好みです。 – phillip

1

あなたはデータリーダーから読み込むように、各列からのデータを持つオブジェクトを取り込みます。この時点で、重複を心配しないでください:

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; 
    } 
} 

、あなたは階層の個々のレベルを取得するためにLINQを使用することができます

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])); 
} 

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

関連する問題