LINQ查询返回DataTable类型【转】
在使用LINQ查询的时候,一般我们会返回List<T>或IList<T>类型,如下所示: 例1: public List<TSample> GetList() { using (BPDataContext db = new BPDataContext(TCTC_ConnectionStrings.connStr)) { var q = from p in db.TSample select p; return q.ToList(); } } 例1实现的是一个最简单的列表查询,返回的是List<TSample>类型,本身没有任何问题!但是如果现在希望查询TSample表中的指定几列,代码应该是: var q = from p in db.TSample select new { p.FID, p.FName }; return q.ToList(); 现在问题是返回类型该写什么呢?new{p.FID,p.FName}已经不是TSample类型了,又不支持返回值为List<T>的! 可能的解决方案是: 方法一: 先扩展一个类SampleEx public class SampleEx { public Guid FID { get; set; } public string FName { get; set; } } 然后返回List<SampleEx>类型 public List<SampleEx> GetList() { using (BPDataContext db = new BPDataContext(TCTC_ConnectionStrings.connStr)) { var q = from p in db.TSample select new SampleEx() { FID = p.FID, FName = p.FName }; return q.ToList(); } } 这样就达到了我们想要的目标。 问题是解决了,但是再仔细想想这样的解决方案似乎可行性不强。因为在实际开发中我们经常查询两个表join查询,那么重新组合的字段就比较多了,要每个都去扩展单独的类,工作量太大!有些人可能会想到用试图,然后dbml会自动帮我们生成类,但是这个工作量也应该不小,天天建试图,要频繁跟新dbml文件的方式不怎么合理!最期望的方式就是不用构造自定义类型,经过转换返回我们需要的类型! 下面通过一个方法来实现返回DataTable类型: /// <summary> /// LINQ返回DataTable类型 /// </summary> /// <typeparam name="T"> </typeparam> /// <param name="varlist"> </param> /// <returns> </returns> public static DataTable ToDataTable<T>(IEnumerable<T> varlist) { DataTable dtReturn = new DataTable(); // column names PropertyInfo[] oProps = null; if (varlist == null) return dtReturn; foreach (T rec in varlist) { if (oProps == null) { oProps = ((Type)rec.GetType()).GetProperties(); foreach (PropertyInfo pi in oProps) { Type colType = pi.PropertyType; if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) { colType = colType.GetGenericArguments()[0]; } dtReturn.Columns.Add(new DataColumn(pi.Name, colType)); } } DataRow dr = dtReturn.NewRow(); foreach (PropertyInfo pi in oProps) { dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue (rec, null); } dtReturn.Rows.Add(dr); } return dtReturn; } 如何使用?如下示例: /// <summary> /// 根据获取多个器具信息 /// </summary> /// <param name="IDs"></param> /// <returns></returns> public DataTable GetByIDs(List<string> IDs) { using (BPDataContext db = new BPDataContext(TCTC_ConnectionStrings.connStr)) { var p = (from c in db.TSample where IDs.Contains(c.FID.ToString()) select new { c.FID, c.FName, c.FCode, c.FType, c.FProductUnit, c.FDeviceNo }).ToList(); return LinqToDataTable.ToDataTable(p); } } 到这里就达到了我们预期的方式!返回DataTable,那么对后面数据源直接绑定,或序列化为Json都非常方便了!