2009-05-19 61 views
2

這是更仿製藥方面比亞音速一個問題:使用Subsonic.Select()方法ExecuteTypedList用字符串

試想一下,如果有以下代碼:

List<int> result = 
     DB.Select(Product.Columns.Id) 
     .From<Product>() 
     .ExecuteTypedList<int>(); 

這偉大工程,並返回一個泛型列表用我的產品表中的ID。

但是,如果我想要得到的產品名稱的列表:

List<String> result = 
     DB.Select(Product.Columns.ProductName) 
     .From<Product>() 
     .ExecuteTypedList<String>(); 

它拋出一個編譯器消息(德國翻譯):

「串」必須是一個非抽象鍵入 與公共構造函數沒有 參數,以便用作泛型類型 或通用方法 「SubSonic.SqlQuery.ExecuteTypedList()」 作爲參數「T」。

原因:字符串中有沒有空的構造器:

int i = new int;  // works 
String s = new String; // compiler error: "string" does not contain a constructor that takes '0' argument 

如果我使用一個 List<Object>,而不是它的工作原理 ,但有一個更優雅的方式,在那裏我可以用List<String>

更新:List<Object>不起作用。我確實得到一個對象列表,但似乎是不包含我的ProductNames的對象(object.ToString()返回{Object}

回答

6

帶有一點點的dotnet魔術可以在不打補丁的亞音速代碼。

  1. 創建一個新類SubsonicSqlQueryExtensionMethods和放棄這一代碼:

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    
    using SubSonic; 
    
    namespace MyUtil.ExtensionMethods 
    { 
        public static class SubSonicSqlQueryExtensionMethods 
        { 
         public static List<String> ExecuteTypedList(this SqlQuery qry) 
         { 
          List<String> list = new List<String>(); 
          foreach (System.Data.DataRow row in qry.ExecuteDataSet().Tables[0].Rows) 
          { 
           list.Add((String)row[0]); 
          } 
          return list; 
         } 
        } 
    } 
    

現在添加引用MyUtil。ExtensionMethods到類:

using MyUtil.ExtensionMethods; 

最後這個作品:

List<String> result = DB.Select(User.Columns.Name).From<User>().ExecuteTypedList(); 

請注意,上面的擴展方法重載不帶類型參數的ExecuteTypedList()方法(遺憾的是這個片段需要DOTNET 3.5,但對我來說,它的作品)

0

嗯,我可以想到這一點,但它幾乎沒有優雅:

List<string>result=DB.Select(Products.Columns.ProductName) 
.From<Product>() 
.ExecutTypedList<StringBuilder>() 
.ConvertAll(sb=>sb.ToString()); 
+0

這是行不通的。它會嘗試將結果列與StringBuilder上的屬性進行匹配。 – 2009-05-19 15:52:34

0

它看起來不像SubSonic對帶有字符串值的ExecuteTypedList的適當支持。構建列表的方法首先查找SubSonic類型,如果沒有匹配檢查以查看T是否爲值類型。由於字符串不是值類型,因此它會貫穿到試圖將屬性名稱與返回的列名匹配的最後一個條件。由於字符串沒有可以分配的屬性名稱,因此失敗。

參見:BuildTypedResult方法:http://subsonicproject.googlecode.com/svn/trunk/SubSonic/SqlQuery/SqlQuery.cs

+0

這是真的,但正如上面提到的,主要問題是String沒有帶0參數的構造函數,所以我甚至不能用上面的代碼編譯我的程序集。 我想也許會有一種方法來告訴它應該採取另一個構造函數的泛型方法。 類似於(我知道doesen't工作): .ExecutTypedList (); 我想我會爲Subsonic創建一個ExecuteTypedStringList()方法。 – 2009-05-19 16:39:50

1

我知道我遲到了這個派對,但我找到了一個'欺騙'這個問題的整潔方式。

List<String> result = 
    DB.Select() 
    .From<Product>() 
    .ExecuteTypedList<String>().Select(p => p.ProductName).ToList<String>(); 

這對我來說就像是一種魅力。

希望能幫助某個地方的人,因爲我相信你已經遠遠超過了這個問題。

+1

這對亞音速2不起作用,因爲通用的`ExecuteTypedList`方法有一個`new`約束,它要求每個泛型參數都有一個空構造函數(該字符串沒有)。你可能在你的例子中的意思是`ExecuteTypedList ()`。 – 2010-08-17 19:26:40