Linq To DataTable

 Linq已经让我们感觉不到Query的难点, 它让我们很容易的实现高难度的Query。 或许剩下的问题, 也许是很简单的问题就是如何保存这些Query结果?    

    例如:

  1.             var _result = DAL.Utility.SelectAll<Customer>();
  2.             var _filter =
  3.                 from q in _result
  4.                 where q.CustomerID.StartsWith("B")
  5.                 select new
  6.                 {
  7.                     q.CustomerID,
  8.                     q.ContactName,
  9.                     q.CompanyName
  10.                 };

    _result 是搜索所有Customer的结果,_filter 是 _result 中 CustomerID 以“B”开始的{CustomerID , ContactName, CompanyName} 集合,但是这个匿名类型就没办法作为变量 return 给另外一个方法调用。 

    可能把这个{CustomerID , ContactName, CompanyName} 集合反射到一个DataTable类型是比较符合一般数据库需求的, 或许说这也是某些旧系统轻松插上Linq翅膀的一种方案。

    下面给出两个Convert To DataTable 的方法(某种意义上是一样的):    

  1.         public static System.Data.DataTable LinqToDataTable<T>(IEnumerable<T> data)
  2.         {
  3.             var dt = new System.Data.DataTable();
  4.             var ps = typeof(T).GetProperties().ToList();
  5.             ps.ForEach(p => dt.Columns.Add(p.Name, p.PropertyType));
  6.             foreach (T t in data)
  7.             {
  8.                 var dr = dt.NewRow();
  9.                 var vs = from p in ps select p.GetValue(t, null);
  10.                 var ls = vs.ToList();
  11.                 int i = 0;
  12.                 ls.ForEach(c => dr[i++] = c);
  13.                 dt.Rows.Add(dr);
  14.             }
  15.             return dt;
  16.         }
  17.         public static System.Data.DataTable ToDataTable<T>(IEnumerable<T> data)
  18.         {
  19.             var dt = new System.Data.DataTable();
  20.             var ps= System.ComponentModel.TypeDescriptor.GetProperties(typeof(T));
  21.             foreach (System.ComponentModel.PropertyDescriptor dp in ps )
  22.                 dt.Columns.Add(dp.Name, dp.PropertyType);
  23.             foreach (T t in data)
  24.             {
  25.                 var dr = dt.NewRow();
  26.                 foreach (System.ComponentModel.PropertyDescriptor dp in ps)
  27.                     dr[dp.Name] = dp.GetValue(t);
  28.                 dt.Rows.Add(dr);
  29.             }
  30.             return dt;
  31.         }

    下面给出一个Testing Project 来测试一下这两个方法:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using DLinq;
  6. using Toolkits;
  7. namespace ToolkitsTest
  8. {
  9.     class Program
  10.     {
  11.         static void Main(string[] args)
  12.         {
  13.             ToDataTableTest();
  14.         }
  15.         private static void ToDataTableTest()
  16.         {
  17.             var _result = DAL.Utility.SelectAll<Customer>();
  18.             var _filter =
  19.                 from q in _result
  20.                 where q.CustomerID.StartsWith("B")
  21.                 select new
  22.                 {
  23.                     q.CustomerID,
  24.                     q.ContactName,
  25.                     q.CompanyName
  26.                 };
  27.             var dt1= BLReflection.LinqToDataTable(_filter);
  28.             var dt2= BLReflection.ToDataTable(_filter);
  29.             var _str1 = StringExtension.ToString(dt1);
  30.             var _str2 = StringExtension.ToString(dt2);
  31.             Console.WriteLine(_str1);
  32.             Console.WriteLine(_str2);
  33.             Console.Read();
  34.         }
  35.     }
  36. }

    相信看过前两篇文章的人都应该记得StringExtension类了, 这里增加了一个方法ToString (System.Data.DataTable data)

  1.         public static string ToString(System.Data.DataTable data)
  2.         {
  3.             StringBuilder sb = new StringBuilder();
  4.             int colCount = data.Columns.Count;
  5.             foreach (System.Data.DataRow dr in data.Rows)
  6.             {
  7.                 for (int i = 0; i < colCount; i++)
  8.                 {
  9.                     string s = (dr[i] == null ? string.Empty : dr[i].ToString());
  10.                     sb.Append(s);
  11.                     sb.Append(", ");
  12.                 }
  13.                 sb.AppendLine();
  14.             }
  15.             return sb.ToString();
  16.         }

    最后,测试结果应该是这样的(两个方法转换的结果都一样):


BERGS, Christina Berglund, Berglunds snabbk?p,
BLAUS, Hanna Moos, Blauer See Delikatessen,
BLONP, Frédérique Citeaux, Blondesddsl père et fils,
BOLID, Martín Sommer, Bólido Comidas preparadas,
BONAP, Laurence Lebihan, Bon app',
BOTTM, Elizabeth Lincoln, Bottom-Dollar Markets,
BSBEV, Victoria Ashworth, B's Beverages,

 

BERGS, Christina Berglund, Berglunds snabbk?p,
BLAUS, Hanna Moos, Blauer See Delikatessen,
BLONP, Frédérique Citeaux, Blondesddsl père et fils,
BOLID, Martín Sommer, Bólido Comidas preparadas,
BONAP, Laurence Lebihan, Bon app',
BOTTM, Elizabeth Lincoln, Bottom-Dollar Markets,
BSBEV, Victoria Ashworth, B's Beverages,

上一篇 :N层架构中使用LINQ联合查询多表结果集的返回
下一篇 :Linq 数据库通用的操作类