2011-12-02 93 views
0

也許SO不是這個地方,如果不是,我很抱歉,但我不禁想到有一個更好的方法來做到這一點。這看起來像是一個嚴重而不是很乾淨的方法,用於檢查我正在處理的結果集,然後執行相應的操作。任何人有任何建議? (請忽略我總是返回null的事實)。乾淨的設計來處理從IDataReader的多個結果集

public MemberDto Load(long entityId) 
    { 
     using (var cn = new SqlConnection(@"connectionstringstuff")) 
     { 
      cn.Open(); 
      using (SqlCommand cm = cn.CreateCommand()) 
      { 
       cm.CommandText = "Client.[MemberGet]"; 
       cm.CommandType = CommandType.StoredProcedure; 

       cm.Parameters.AddWithValue("@EntityId", entityId); 

       using (IDataReader dr = cm.ExecuteReader()) 
       { 
        var memberModel = new MemberDto(); 
        do 
        { 
         while (dr.Read()) 
         { 
          var sdr = new SafeDataReader(dr); 
          var firstColumn = sdr.GetName(0); 
          if (firstColumn.StartsWith("Attribute")) 
          { 
           AddAttribute(memberModel, sdr); 
          } 
          else if (firstColumn.StartsWith("AlternateId")) 
          { 
           AddAlternateId(memberModel, sdr); 
          } 
          else 
          { 
           memberModel.ClientId = sdr.GetInt64("ClientId"); 
           memberModel.Id = sdr.GetInt64("EntityId"); 
           memberModel.Name = sdr.GetString("EntityName"); 
          } 
         } 
        } while (dr.NextResult()); 
       } 
      } 
     } 

     return null; 
    } 

    private void AddAttribute(MemberDto model, SafeDataReader reader) 
    { 
     model.Attributes.Add(
      reader.GetInt32("AttributeTypeId").As<EntityAttributeType>(), 
      reader.GetString("Value")); 
    } 

    private void AddAlternateId(MemberDto model, SafeDataReader reader) 
    { 
     model.Attributes.Add(
      reader.GetInt32("AlternateIdTypeId").As<EntityAttributeType>(), 
      reader.GetString("Value")); 
    } 
+0

難道你不知道哪個結果集排在第一位嗎? –

+0

是的,我控制着SP。我只是希望不必依賴訂單,以防因某種原因將來有人改變它。我並不完全反對,但我試圖迴避它。 – phreak3eb

+1

@ phreak3eb該訂單應被視爲SP,IMO合同的一部分。如果這種變化,應該預計來電者需要改變。 –

回答

0

我們接近的方式不是循環下一個結果,而是顯式編碼它以匹配底層數據。這種方法的預期結果在某種程度上更直觀地表明瞭這一點(當然,我認爲)。

這裏是一個重寫示例,假設順序是membermodel,attributes和alternates。

while (dr.Read()) 
    { 
     var sdr = new SafeDataReader(dr); 
     memberModel.ClientId = sdr.GetInt64("ClientId"); 
     memberModel.Id = sdr.GetInt64("EntityId"); 
     memberModel.Name = sdr.GetString("EntityName"); 
    } 
    if (dr.NextResult()) 
    { 
     while (dr.Read()) 
     { 
      AddAttribute(memberModel, new SafeDataReader(dr)); 
     } 
    } 
    if (dr.NextResult()) 
    { 
     while (dr.Read()) 
     { 
      AddAlternateId(memberModel, new SafeDataReader(dr)); 
     } 
    } 
+0

經過很多考慮和玩耍之後,我繼續回到Marc Gravell的上面的原始評論,結果集的順序應該是proc合同的一部分。話雖如此,我希望我能接受兩個答案,因爲competent_tech和tcarvin都有我的解決方案。我選擇了這個答案,因爲它不涉及每個響應都發回一個元數據結果集。所以現在我期望結果集按給定的順序排列,但也會用一些特定的類將記錄綁定到模型。謝謝各位的意見。 – phreak3eb

+0

有關SafeDataReader的任何示例? – Kiquenet

0

也許返回多個結果所有的SP應該包括其中第一個結果集在返回的結果集specifiying其順序爲:

dr = multRsCmd.ExecureReader(); 

// first rs is always the meta 
List<string> resultSetIds = new List<string>(); 
while (dr.Read()) 
    resultSetIds.Add(dr[0] 

foreach (string rsId in resultSetIds) 
{ 

    if (!dr.NextResult()) 
     break; // or throw, should not happen 

    if (rsId == "ClientDataWithAttribute") 
    { 
     // code to handle the exact rs layout for ClientDataWithAttribute 
     // 
     // 
    } 
    else if (rsId == "ClientDataWithAltId") 
    { 
     // code to handle the exact rs layout for ClientDataWithAltId 
     // 
     // 
    } 
    else if (rsId == "ClientData") 
    { 
     // code to handle the exact rs layout for ClientData 
     // 
     // 
    } 

} 

這當然尖叫出來重構:

dr = multRsCmd.ExecureReader(); 

// first rs is always the meta 
List<string> resultSetIds = new List<string>(); 
while (dr.Read()) 
    resultSetIds.Add(dr[0] 

foreach (string rsId in resultSetIds) 
{ 

    if (!dr.NextResult()) 
     break; // or throw, should not happen 

    // pull subclass out of registry of readers 
    ResultSetReader rsr = ResultSetReaders.Find(rsId); 

    // subclass cleanly holds the layout-dependent logic 
    memberModel = rsr.FromDataReader(dr); 

} 

看起來相當乾淨,但您甚至可以在ResultSetReader中添加默認行爲以從配置文件或其他源驅動DTO屬性映射,並且只在你有特殊的條件。你明白了。