2017-08-01 43 views
0

我有一個SQL查詢,爲我提供我的數據,我有時應該有行應該被聚集(數據與命令對齊)。數據按字段CAPName分組。逐行瀏覽這些行,我需要決定是否應該啓動一個新列表(CAPName的內容與之前的迭代不同),還是應該添加(已經)啓動的列表(來自之前的迭代)。
我的痛苦在於relatedCapabilitySystem列表聲明的位置。
我想在if語句中聲明它(因爲,正如我所說的,我需要決定是否應該添加上一次迭代的列表,或者是否應該啓動一個新列表),但是我不能編譯器會拋出一個異常,因爲RLCapSys.Add(rCs);在這個內容中是不存在的(這在理論上是正確的)。我明白爲什麼編譯器會拋出這個異常。但是,如果我在「更高」級別聲明該列表,那麼我總是會有一個新列表,如果該項目應該添加到迭代中定義的列表中(1個或更多)
所以我想實現的是,生成列表RLCapSys並添加到它,以防上一次迭代包含相同的CAPName(用於集羣),否則創建一個新列表。c#如何決定是否要添加到子列表或開始新的

SqlCommand cmdDetail = new SqlCommand(SQL_SubSytemsToCapability, DBConDetail); 
SqlDataReader rdrDetail = cmdDetail.ExecuteReader(); 

List<relatedCapility> RLCaps = new List<relatedCapility>(); 
string lastCapShown = null; 

while (rdrDetail.Read()) 
{ 
    List<relatedCapabilitySystem> RLCapSys = new List<relatedCapabilitySystem>(); 
    if (lastCapShown != rdrDetail["CAPName"].ToString()) 
    { 
     //List<relatedCapabilitySystem> RLCapSys2 = new List<relatedCapabilitySystem>(); 
     relatedCapility rC = new relatedCapility 
     { 
      Capability = rdrDetail["CAPName"].ToString(), 
      systemsRelated = RLCapSys, 

     }; 
     RLCaps.Add(rC); 
    } 

    relatedCapabilitySystem rCs = new relatedCapabilitySystem 
    { 
     system = rdrDetail["name"].ToString(), 
     start = rdrDetail["SysStart"].ToString(), 
     end = rdrDetail["SysEnd"].ToString(), 
    }; 
    RLCapSys.Add(rCs); 

    // method to compare the last related Capability shown create a new related Capabilty entry or add to the existing releated Capabilty related system list 
    lastCapShown = rdrDetail["CAPName"].ToString(); 

} 
DBConDetail.Close(); 

和原因completness的(但我覺得這裏是不是需要它):

internal class CapabilitiesC 
{ 
    public List<Capability>Capabilities{ get;set;} 
} 

public class Capability 
{ 
    public string name { get; internal set; } 
    public string tower { get; internal set; } 
    public string color { get; internal set; } 
    public List<relatedCapility> related { get; set; } 
} 

public class relatedCapility 
{ 
    public string Capability { get; set; } 
    public List<relatedCapabilitySystem> systemsRelated { get; set; } 
} 

public class relatedCapabilitySystem 
{ 
    public string system { get; set; } 
    public string start { get; set; } 
    public string end { get; set; } 

} 

回答

0

我已經現在就開始工作。 Thx大家爲你的幫助。
@martin,thx爲你的解決方案,你已經付出了相當的努力,但這需要我完全重寫我的代碼。如果我再次遇到類似的問題,我相信你的方法會起作用,併成爲我的下一個方法。
這是其他答案的組合,幫助我弄清楚了。讓我告訴你我結束了什麼:

  SqlCommand cmdDetail = new SqlCommand(SQL_SubSytemsToCapability, DBConDetail); 
      SqlDataReader rdrDetail = cmdDetail.ExecuteReader(); 

      List<relatedCapility> RLCaps = new List<relatedCapility>(); 
      List<relatedCapabilitySystem> RLCapSys = new List<relatedCapabilitySystem>(); 

      string lastCapShown = null; 
      while (rdrDetail.Read()) 
      { 

       if (lastCapShown != rdrDetail["CAPName"].ToString()) 
       { 
        RLCapSys = relatedCapabilitySystemList(); 
        relatedCapility rC = new relatedCapility 
        { 
         Capability = rdrDetail["CAPName"].ToString(), 
         systemsRelated = RLCapSys, 
        }; 
        RLCaps.Add(rC); 
       } 

       relatedCapabilitySystem rCs = new relatedCapabilitySystem 
       { 
        system = rdrDetail["name"].ToString(), 
        start = rdrDetail["SysStart"].ToString(), 
        end = rdrDetail["SysEnd"].ToString(), 
       }; 

       RLCapSys.Add(rCs); 

       // method to compare the last related Capability shown create a new related Capabilty entry or add to the existing releated Capabilty related system list 
       lastCapShown = rdrDetail["CAPName"].ToString(); 

      } 
      DBConDetail.Close(); 

所以這就是已經顯示的部分,包括我的變化。另外,我補充這一點:

 private List<relatedCapabilitySystem> relatedCapabilitySystemList() 
    { 
     List<relatedCapabilitySystem> RLCapSys = new List<relatedCapabilitySystem>(); 
     return RLCapSys; 
    } 

現在我有了新的參考名單的每次變化CapName被加入到「高」名單。在我開始重複分配同一個清單而不是新清單的問題之前,
所以thx再次爲你的努力。

0

爲什麼不直接將其指定爲NULL。該模式將爲

List<> myList = null; 
if(condition) 
{ 
    myList = new List<>(); 
} 
else 
{ 
    myList = previousList; 
} 
myList.Add(); 
previousList = myList; 
+0

Thx的提示,我忘了提及這;) 我已經試過這個通過添加上面的while循環列表。我添加了'List RLCapSys = null;'但是這會在if語句中創建一個例外。其中的內容如下:「名爲'RLCapSys'的本地或參數不能在此範圍內聲明,因爲該名稱在封閉的本地範圍中用於定義本地或參數。 – Janbro

+1

@Janbro:您沒有得到異常。編譯錯誤,因爲你用嵌套塊中的代碼'List RLCapSys = null;'聲明瞭一個具有相同名字的列表變量,你應該刪除內部聲明。如果你在那時需要給'列表(我不這麼認爲)你應該使用代碼'RLCapSys = null;'。這將爲你在循環外部聲明的變量賦予'null'。 –

2

您的代碼的目的是獲取輸入數據並按功能對其進行分組。但是,這並不明顯。您可以更改您的代碼以使用LINQ,以便更容易理解並在此過程中解決您的問題。

首先,您需要一個類型來表示數據庫中的記錄。由於缺乏更好的名字,我會用Record

class Record 
{ 
    public string System { get; set; } 
    public string Start { get; set; } 
    public string End { get; set; } 
    public string Capabilty { get; set; } 
} 

然後,您可以創建一個迭代器塊從數據庫返回的所有記錄(如實體框架避免了大多數代碼使用OR映射器,您甚至可以轉變一些從您的計算機到數據庫服務器的工作)的:

IEnumerable<Record> GetRecords() 
{ 
    // Code to create connection and command (preferably in a using statement) 
    SqlDataReader rdrDetail = cmdDetail.ExecuteReader(); 
    while (rdrDetail.Read()) 
    { 
     yield return new Record { 
      System = rdrDetail["name"].ToString(), 
      Start = rdrDetail["SysStart"].ToString(), 
      End = rdrDetail["SysEnd"].ToString(), 
      Capability = rdrDetail["CAPName"].ToString() 
     }; 
    } 
    // Close connection (proper using statement will do this) 
} 

最後,你可以使用LINQ進行分組:

var RLCaps = GetRecords() 
    .GroupBy(
     record => record.Capability, 
     (capability, records) => new relatedCapility 
      { 
       Capability = capability , 
       systemsRelated = records 
        .Select(record => new relatedCapabilitySystem 
         { 
          system = record.System, 
          start = record.Start, 
          end = record.End 
         }) 
        .ToList() 
      }) 
    .ToList(); 
相關問題