Funny Linq Part3: Linq To DataTable

Funny Linq Part3: 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,

 

 

2009年5月16日更新:

另一种方法:


        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;
        }

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值