使用带有String的Subsonic.Select()ExecuteTypedList方法
这是一个关于generics而不是亚音速的问题:
想象一下,如果有以下代码:
List result = DB.Select(Product.Columns.Id) .From() .ExecuteTypedList();
这很好用,并返回一个包含我的Product表中的ID的通用列表。
但是,如果我想获得ProductName的列表:
List result = DB.Select(Product.Columns.ProductName) .From() .ExecuteTypedList();
它会抛出编译器消息(翻译自德语):
“string”必须是非抽象类型,具有不带参数的公共构造函数,以便用作generics类型或在generics方法“SubSonic.SqlQuery.ExecuteTypedList()”中用作参数“T”。
cause:String没有空的构造函数:
int i = new int; // works String s = new String; // compiler error: "string" does not contain a constructor that takes '0' argument
如果我使用 ,但是有更优雅的方式,我可以使用List
而不是它有效List
吗?
更新: List
不起作用。 我确实得到了一个对象列表,但这似乎是“空”对象,不包含我的ProductNames(object.ToString()返回{Object}
)
有点dotnet魔术,没有修补亚音速代码是可能的。
-
创建一个新类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
ExecuteTypedList(this SqlQuery qry) { List list = new List (); foreach (System.Data.DataRow row in qry.ExecuteDataSet().Tables[0].Rows) { list.Add((String)row[0]); } return list; } } }
现在将MyUtil.ExtensionMethods的引用添加到您的类:
using MyUtil.ExtensionMethods;
最后这个工作:
List result = DB.Select(User.Columns.Name).From().ExecuteTypedList();
请注意,上面的扩展方法重载ExecuteTypedList()方法没有type-argument(不幸的是这段代码需要dotnet 3.5,但对我来说它有效)
我知道我参加这个派对已经很晚了,但我发现了一个“欺骗”这个问题的巧妙方法。
List result = DB.Select() .From() .ExecuteTypedList().Select(p => p.ProductName).ToList ();
这对我来说就像一个魅力。
希望能在某个地方帮助某人,因为我相信你已经远远超过了这个问题。
好吧,我可以想到这一点,但它不是更优雅:
Listresult=DB.Select(Products.Columns.ProductName) .From() .ExecutTypedList() .ConvertAll(sb=>sb.ToString());
它看起来不像SubSonic对带有字符串值的ExecuteTypedList有适当的支持。 首先构建列表的方法查找SubSonic类型,如果没有匹配检查,则查看T是否为值类型。 由于string不是值类型,因此它会尝试将属性名称与返回的列名称匹配的最后一个条件。 由于string没有可以分配的属性名称,因此失败。
请参阅:BuildTypedResult方法: http ://subsonicproject.googlecode.com/svn/trunk/SubSonic/SqlQuery/SqlQuery.cs