一、DataTable的扩展方法:

1、DataTable转Linq:AsEnumerable 方法

返回的EnumerableRowCollection<DataRow> 实现了 IEnumerable<T>接口。其中泛型参数T是DataRow。

此对象可用在 LINQ表达式或方法查询中。

语法:

  1. public static EnumerableRowCollection<DataRow> AsEnumerable (this DataTable source);

在以下示例中,一个 DataColumn 数据表ProductName,提取ProductName值,然后将值输出。

  1. DataTable table = new DataTable();
  2. table.Columns.Add("ID");
  3. table.Columns.Add("ProductName");
  4.  
  5. table.Rows.Add("1", "Chai");
  6. table.Rows.Add("2", "Queso Cabrales");
  7. table.Rows.Add("3", "Tofu");
  8.  
  9. var productNames = from products in table.AsEnumerable()
  1. select products.Field<string>("ProductName");
  2. Console.WriteLine("Product Names: ");
  3. foreach (string productName in productNames)
  4. {
  5. Console.WriteLine(productName);
  6. }

注意:转成EnumerableRowCollection后,需要对两个这样的行集合进行操作,如:Distinct,Union,Except,Intesect,SequenceEqual都需要对数据源的元素进行相等比较,需要使用专门为Linq To Datatable新增加的DataRowComparer作为参数(实现了IEqulityComparer接口),用于比较DataRow的值(而不是引用比较)。否则,根本不能达到预期操作。

  1. IEnumerable<DataRow> distinctTable = table.AsEnumerable().Distinct(DataRowComparer.Default);

2、Linq转DataTable

(1)返回DataTable,其中包含的副本DataRow对象。

  1. public static DataTable CopyToDataTable<T> (this IEnumerable<T> source) where T : DataRow;

以下示例查询 SalesOrderHeader 表的订单后 2001 年 8 月 8 日,并使用CopyToDataTable方法来创建DataTable从该查询。

  1. DataTable orders = ds.Tables["SalesOrderHeader"];
  2.  
  3. IEnumerable<DataRow> query =
  4. from order in orders.AsEnumerable()
  5. where order.Field<DateTime>("OrderDate") > new DateTime(2001, 8, 1)
  6. select order;
  7.  
  8. // Create a table from the query.
  9. DataTable boundTable = query.CopyToDataTable<DataRow>();

(2)副本表的DataRow到指定的对象DataTable。

  1. public static void CopyToDataTable<T> (this IEnumerable<T> source, DataTable table, LoadOption options) where T : DataRow;

LoadOption:当使用 LoadLoad 方法时控制数据源中的值如何应用至现有行。

  1. OverwriteChanges:    传入此行的值将同时写入每列数据的当前值和原始值版本。
  2. PreserveChanges:   传入此行的值将写入每列数据的原始值版本。 每列数据的当前版本不变化。 这是默认设置。
  3. Upsert  : 传入此行的值将写入每列数据的当前版本。 每列数据的原始版本不变化。

以下示例:如果tableold表设置了主键,则可以合并记录,否则追加。

  1. table.AsEnumerable().CopyToDataTable(tableold,LoadOption.OverwriteChanges);

tips:默认情况下(没对表进行操作),数据行的Original版本是不存在的,视图访问将报错。可以在访问之前使用DataRow.HasVersion来判断,也可以通过调用DataRow.AcceptChanges()方法来建立Original版本,避免异常发生。

二、DataRow中的扩展方法:

(1)获取字段值

Field:提供对 DataRow 中的每个列值的强类型访问。

  1. public static T Field<T> (this DataRow row, string columnName);

举例:

  1. foreach (DataRow row in table.AsEnumerable())
  2. {
  3. row.Field<int>("Id");
  4. row.Field<string>("Name", DataRowVersion.Original);
  5. }

(2)设置字段值

Set​Field:为 DataRow 中的指定列设置一个新值。

  1. public static void SetField<T> (DataRow row, string columnName, T value);

如果value是null,则SetField方法转换null值设置为DBNull.Value。

举例:

  1. var rows = from s in table.AsEnumerable()
  2. where s.Field<string>("Name") == "c"
  3. select s;
  4. rows.Single<DataRow>().SetField("Name", "cc");

三、Linq To DataTable的常见用法。

1、查询:

  1. DataTable table = new DataTable();
  2. table.Columns.Add("ID", Type.GetType("System.Int32"));
  3. table.Columns.Add("PID", Type.GetType("System.Int32"));
  4. table.Columns.Add("CreateDate", Type.GetType("System.DateTime"));
  5.  
  6. table.Rows.Add(1, 2, "2010-1-1");
  7. table.Rows.Add(2, 3, "2011-1-1");
  8. table.Rows.Add(3, 3, "2012-1-1");
  9. table.Rows.Add(4, 2, null);
  10.  
  11. var rows = from s in table.AsEnumerable()
  12. where s.Field<int>("ID") > 1 && !s.IsNull("CreateDate")
  13. select new
  14. {
  15. ID = s["ID"],
  16. CreateDate = s["CreateDate"]
  17. };
  18. rows.ToList().ForEach(m => Console.WriteLine(m.ID + "-" + m.CreateDate));//2-2011-01-01 0:00:00 3-2012-01-01 0:00:00

2、分组:

  1. var query = from r in table.AsEnumerable()
  2. group r by new
  3. {
  4. PID = r.Field<int>("PID")
  5. } into g
  6. select new
  7. {
  8. Pid = g.Key.PID,
  9. FirstCreateDate = g.First().Field<DateTime>("CreateDate"),
  10. IDS = string.Join(",", g.Select(n => n.Field<int>("ID")).ToArray()),
  11. Count = g.Count(q => q.Field<int>("ID") > 1),
  12. Sum1 = g.Sum(q => q.Field<int>("ID"))
  13. };
  14. query.ToList().ForEach(m => Console.WriteLine(m.Pid + "-" + m.FirstCreateDate + "-" + m.IDS));//2-2010-01-01 0:00:00-1,4 3-2011-01-01 0:00:00-2,3

例2:按PID分组,获取倒数第二条信息

  1. var query1 = from r in table.AsEnumerable()
  2. where new int[] { 3, 4 }.Contains(r.Field<int>("PID"))
  3. orderby r.Field<DateTime>("CreateDate") descending
  4. group r by r.Field<int>("PID") into g
  5. let n = (from d in g.Take(2).Skip(1) select d).FirstOrDefault()
  6. select new
  7. {
  8. PID = g.Key,
  9. ID = n.Field<int>("ID"),
  10. CreateDate = n.Field<DateTime>("CreateDate")
  11. };
  12. query1.ToList().ForEach(m => Console.WriteLine(m.PID + "-" + m.ID + "-" + m.CreateDate));//3-2-2011-01-01 0:00:00

3、Join组合查询:

  1. var result = from t1 in table.AsEnumerable()
  2. join t2 in table.AsEnumerable() on
  3. t1.Field<int>("ID") equals t2.Field<int>("ID")
  4. where t2.Field<DateTime?>("CreateDate") < DateTime.Today || !t2.Field<DateTime?>("CreateDate").HasValue
  5. select new
  6. {
  7. ID = t2.Field<int>("ID"),
  8. CreateDate = t1.Field<DateTime?>("CreateDate")
  9. };
  10. result.ToList().ForEach(m => Console.WriteLine(m.ID + "-" + m.CreateDate));

LINQ to DataSet,对离线数据的Linq支持、AsEnumeable()的更多相关文章

  1. LINQ系列:LINQ to DataSet的DataTable操作

    LINQ to DataSet需要使用System.Core.dll.System.Data.dll和System.Data.DataSetExtensions.dll,在项目中添加引用System. ...

  2. LINQ(LINQ to DataSet)

    http://www.cnblogs.com/SkySoot/archive/2012/08/21/2649471.html DataTable.Select()方法使用和 SQL 相似的过滤语法从 ...

  3. C#数据操作LINQ

    Linq是language integrated query的缩写,即"语言集成查询"之意. Linq主要包含四个组件,Linq to object.Linq to XML.Lin ...

  4. 泛型 Field 和 SetField 方法 (LINQ to DataSet)

    LINQ to DataSet 为 DataRow 类提供用于访问列值的扩展方法:Field 方法和 SetField 方法.这些方法使开发人员能够更轻松地访问列值,特别是 null 值.DataSe ...

  5. C# LINQ系列:LINQ to DataSet的DataTable操作 及 DataTable与Linq相互转换

    LINQ to DataSet需要使用System.Core.dll.System.Data.dll和System.Data.DataSetExtensions.dll,在项目中添加引用System. ...

  6. EntityFramework数据持久化 Linq介绍

    一.LINQ概述与查询语法 二.LINQ方法语法基础(重点) 三.LINQ聚合操作与元素操作(重点) 四.数据类型转换(重点) 一.LINQ概述与查询语法 1.LINQ(Language Integr ...

  7. EntityFramework数据持久化 Linq语法应用

    Linq基础语法 LINQ概述 LINQ(Language Integrated Query,语言集成查询)提供了一种跨数据源和数据格式查询的统一模型. LINQ的组成: LINQ To Object ...

  8. Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解

    返回<8天掌握EF的Code First开发>总目录 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LINQ to ...

  9. 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解

    本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...

随机推荐

  1. python 字典dict - python基础入门(15)

    前面的课程讲解了字符串str/列表list/元组tuple,还有最后一种比较重要的数据类型也需要介绍介绍,那就是python字典,俗称:dict. python中的字典可与字符串/列表/元组不同,因为 ...

  2. 洛谷 题解 UVA1151 【买还是建 Buy or Build】

    [题意] 平面上有\(n(n<=1000)\)个点,你的任务是让所有n个点联通.为此,你可以新建一些边,费用等于两个端点的欧几里得距离平方.另外还有\(q(q<=8)\)个套餐可以购买,如 ...

  3. docker(学习笔记)

    # 1. Docker介绍## 1.1 什么是容器?## 1.2 容器的前世今生FreeBASE jail ------> Linux vserverchroot ----> 完整的根文件 ...

  4. Zookeeper开源客户端Curator之事件监听详解

    Curator对Zookeeper典型场景之事件监听进行封装,提供了使用参考.这篇博文笔者带领大家了解一下Curator的实现方式. 引入依赖 对于Curator封装Zookeeper的典型场景使用都 ...

  5. 深度图转伪彩色图(python)

    kinect得到的深度图灰不拉几,人眼很难识别出其中的物体,感知深度的变化. 在做展示的时候,我们往往需要可视化,使用OpenCV的预定义的颜色映射来将灰度图像伪彩色化,在OpenCV中使用apply ...

  6. 【51nod】1776 路径计数

    [51nod]1776 路径计数 我们先把前两种数给排好,排好之后会有\(a + b + 1\)个空隙可以填数,我们计算有\(k\)个空隙两端都是相同字母的方案数 可以用枚举把第二种数分成几段插进去来 ...

  7. VLAN之间通信-三层交换机实现

    1.打开三层交换机的命令行,配置VLAN和设置端口IP enable //进入特权模式 configure terminal //进入全局配置模式 ip routing //启动交换机的路由功能 vl ...

  8. Win10 鼠标右键新建菜单添加自定义文件

    1. 引言 在鼠标右键(右单机)新建菜单中添加自定义文件,例如:写字板,markdown等. 效果图: 2. 操作步骤(以Win10为例) 1. win+R输入regedit进入注册表 2. 这里以添 ...

  9. 1192: 零起点学算法99——The sum problem(C)

    一.题目 http://acm.wust.edu.cn/problem.php?id=1192&soj=0 二.分析 要求从序列1,2,3,,,N,中截取一部分使他们的和为M 输入多组数据 输 ...

  10. LOJ6583 ICPC World Finals 2019何以伊名始(广义后缀自动机)

    对trie建SAM,询问串倒过来跑到的节点的|right|即为答案. #include<bits/stdc++.h> using namespace std; #define ll lon ...