LINQ to DataSet,对离线数据的Linq支持、AsEnumeable()
一、DataTable的扩展方法:
1、DataTable转Linq:AsEnumerable 方法
返回的EnumerableRowCollection<DataRow> 实现了 IEnumerable<T>接口。其中泛型参数T是DataRow。
此对象可用在 LINQ表达式或方法查询中。
语法:
- public static EnumerableRowCollection<DataRow> AsEnumerable (this DataTable source);
在以下示例中,一个 DataColumn 数据表ProductName
,提取ProductName
值,然后将值输出。
- DataTable table = new DataTable();
- table.Columns.Add("ID");
- table.Columns.Add("ProductName");
- table.Rows.Add("1", "Chai");
- table.Rows.Add("2", "Queso Cabrales");
- table.Rows.Add("3", "Tofu");
- var productNames = from products in table.AsEnumerable()
- select products.Field<string>("ProductName");
- Console.WriteLine("Product Names: ");
- foreach (string productName in productNames)
- {
- Console.WriteLine(productName);
- }
注意:转成EnumerableRowCollection后,需要对两个这样的行集合进行操作,如:Distinct,Union,Except,Intesect,SequenceEqual都需要对数据源的元素进行相等比较,需要使用专门为Linq To Datatable新增加的DataRowComparer作为参数(实现了IEqulityComparer接口),用于比较DataRow的值(而不是引用比较)。否则,根本不能达到预期操作。
- IEnumerable<DataRow> distinctTable = table.AsEnumerable().Distinct(DataRowComparer.Default);
2、Linq转DataTable
(1)返回DataTable,其中包含的副本DataRow对象。
- public static DataTable CopyToDataTable<T> (this IEnumerable<T> source) where T : DataRow;
以下示例查询 SalesOrderHeader 表的订单后 2001 年 8 月 8 日,并使用CopyToDataTable方法来创建DataTable从该查询。
- DataTable orders = ds.Tables["SalesOrderHeader"];
- IEnumerable<DataRow> query =
- from order in orders.AsEnumerable()
- where order.Field<DateTime>("OrderDate") > new DateTime(2001, 8, 1)
- select order;
- // Create a table from the query.
- DataTable boundTable = query.CopyToDataTable<DataRow>();
(2)副本表的DataRow到指定的对象DataTable。
- public static void CopyToDataTable<T> (this IEnumerable<T> source, DataTable table, LoadOption options) where T : DataRow;
LoadOption:当使用 Load 或 Load 方法时控制数据源中的值如何应用至现有行。
- OverwriteChanges: 传入此行的值将同时写入每列数据的当前值和原始值版本。
- PreserveChanges: 传入此行的值将写入每列数据的原始值版本。 每列数据的当前版本不变化。 这是默认设置。
- Upsert : 传入此行的值将写入每列数据的当前版本。 每列数据的原始版本不变化。
以下示例:如果tableold表设置了主键,则可以合并记录,否则追加。
- table.AsEnumerable().CopyToDataTable(tableold,LoadOption.OverwriteChanges);
tips:默认情况下(没对表进行操作),数据行的Original版本是不存在的,视图访问将报错。可以在访问之前使用DataRow.HasVersion来判断,也可以通过调用DataRow.AcceptChanges()方法来建立Original版本,避免异常发生。
二、DataRow中的扩展方法:
(1)获取字段值
Field:提供对 DataRow 中的每个列值的强类型访问。
- public static T Field<T> (this DataRow row, string columnName);
举例:
- foreach (DataRow row in table.AsEnumerable())
- {
- row.Field<int>("Id");
- row.Field<string>("Name", DataRowVersion.Original);
- }
(2)设置字段值
SetField:为 DataRow 中的指定列设置一个新值。
- public static void SetField<T> (DataRow row, string columnName, T value);
如果value是null,则SetField方法转换null值设置为DBNull.Value。
举例:
- var rows = from s in table.AsEnumerable()
- where s.Field<string>("Name") == "c"
- select s;
- rows.Single<DataRow>().SetField("Name", "cc");
三、Linq To DataTable的常见用法。
1、查询:
- DataTable table = new DataTable();
- table.Columns.Add("ID", Type.GetType("System.Int32"));
- table.Columns.Add("PID", Type.GetType("System.Int32"));
- table.Columns.Add("CreateDate", Type.GetType("System.DateTime"));
- table.Rows.Add(1, 2, "2010-1-1");
- table.Rows.Add(2, 3, "2011-1-1");
- table.Rows.Add(3, 3, "2012-1-1");
- table.Rows.Add(4, 2, null);
- var rows = from s in table.AsEnumerable()
- where s.Field<int>("ID") > 1 && !s.IsNull("CreateDate")
- select new
- {
- ID = s["ID"],
- CreateDate = s["CreateDate"]
- };
- 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、分组:
- var query = from r in table.AsEnumerable()
- group r by new
- {
- PID = r.Field<int>("PID")
- } into g
- select new
- {
- Pid = g.Key.PID,
- FirstCreateDate = g.First().Field<DateTime>("CreateDate"),
- IDS = string.Join(",", g.Select(n => n.Field<int>("ID")).ToArray()),
- Count = g.Count(q => q.Field<int>("ID") > 1),
- Sum1 = g.Sum(q => q.Field<int>("ID"))
- };
- 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分组,获取倒数第二条信息
- var query1 = from r in table.AsEnumerable()
- where new int[] { 3, 4 }.Contains(r.Field<int>("PID"))
- orderby r.Field<DateTime>("CreateDate") descending
- group r by r.Field<int>("PID") into g
- let n = (from d in g.Take(2).Skip(1) select d).FirstOrDefault()
- select new
- {
- PID = g.Key,
- ID = n.Field<int>("ID"),
- CreateDate = n.Field<DateTime>("CreateDate")
- };
- query1.ToList().ForEach(m => Console.WriteLine(m.PID + "-" + m.ID + "-" + m.CreateDate));//3-2-2011-01-01 0:00:00
3、Join组合查询:
- var result = from t1 in table.AsEnumerable()
- join t2 in table.AsEnumerable() on
- t1.Field<int>("ID") equals t2.Field<int>("ID")
- where t2.Field<DateTime?>("CreateDate") < DateTime.Today || !t2.Field<DateTime?>("CreateDate").HasValue
- select new
- {
- ID = t2.Field<int>("ID"),
- CreateDate = t1.Field<DateTime?>("CreateDate")
- };
- result.ToList().ForEach(m => Console.WriteLine(m.ID + "-" + m.CreateDate));
LINQ to DataSet,对离线数据的Linq支持、AsEnumeable()的更多相关文章
- LINQ系列:LINQ to DataSet的DataTable操作
LINQ to DataSet需要使用System.Core.dll.System.Data.dll和System.Data.DataSetExtensions.dll,在项目中添加引用System. ...
- LINQ(LINQ to DataSet)
http://www.cnblogs.com/SkySoot/archive/2012/08/21/2649471.html DataTable.Select()方法使用和 SQL 相似的过滤语法从 ...
- C#数据操作LINQ
Linq是language integrated query的缩写,即"语言集成查询"之意. Linq主要包含四个组件,Linq to object.Linq to XML.Lin ...
- 泛型 Field 和 SetField 方法 (LINQ to DataSet)
LINQ to DataSet 为 DataRow 类提供用于访问列值的扩展方法:Field 方法和 SetField 方法.这些方法使开发人员能够更轻松地访问列值,特别是 null 值.DataSe ...
- C# LINQ系列:LINQ to DataSet的DataTable操作 及 DataTable与Linq相互转换
LINQ to DataSet需要使用System.Core.dll.System.Data.dll和System.Data.DataSetExtensions.dll,在项目中添加引用System. ...
- EntityFramework数据持久化 Linq介绍
一.LINQ概述与查询语法 二.LINQ方法语法基础(重点) 三.LINQ聚合操作与元素操作(重点) 四.数据类型转换(重点) 一.LINQ概述与查询语法 1.LINQ(Language Integr ...
- EntityFramework数据持久化 Linq语法应用
Linq基础语法 LINQ概述 LINQ(Language Integrated Query,语言集成查询)提供了一种跨数据源和数据格式查询的统一模型. LINQ的组成: LINQ To Object ...
- Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解
返回<8天掌握EF的Code First开发>总目录 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LINQ to ...
- 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...
随机推荐
- python 字典dict - python基础入门(15)
前面的课程讲解了字符串str/列表list/元组tuple,还有最后一种比较重要的数据类型也需要介绍介绍,那就是python字典,俗称:dict. python中的字典可与字符串/列表/元组不同,因为 ...
- 洛谷 题解 UVA1151 【买还是建 Buy or Build】
[题意] 平面上有\(n(n<=1000)\)个点,你的任务是让所有n个点联通.为此,你可以新建一些边,费用等于两个端点的欧几里得距离平方.另外还有\(q(q<=8)\)个套餐可以购买,如 ...
- docker(学习笔记)
# 1. Docker介绍## 1.1 什么是容器?## 1.2 容器的前世今生FreeBASE jail ------> Linux vserverchroot ----> 完整的根文件 ...
- Zookeeper开源客户端Curator之事件监听详解
Curator对Zookeeper典型场景之事件监听进行封装,提供了使用参考.这篇博文笔者带领大家了解一下Curator的实现方式. 引入依赖 对于Curator封装Zookeeper的典型场景使用都 ...
- 深度图转伪彩色图(python)
kinect得到的深度图灰不拉几,人眼很难识别出其中的物体,感知深度的变化. 在做展示的时候,我们往往需要可视化,使用OpenCV的预定义的颜色映射来将灰度图像伪彩色化,在OpenCV中使用apply ...
- 【51nod】1776 路径计数
[51nod]1776 路径计数 我们先把前两种数给排好,排好之后会有\(a + b + 1\)个空隙可以填数,我们计算有\(k\)个空隙两端都是相同字母的方案数 可以用枚举把第二种数分成几段插进去来 ...
- VLAN之间通信-三层交换机实现
1.打开三层交换机的命令行,配置VLAN和设置端口IP enable //进入特权模式 configure terminal //进入全局配置模式 ip routing //启动交换机的路由功能 vl ...
- Win10 鼠标右键新建菜单添加自定义文件
1. 引言 在鼠标右键(右单机)新建菜单中添加自定义文件,例如:写字板,markdown等. 效果图: 2. 操作步骤(以Win10为例) 1. win+R输入regedit进入注册表 2. 这里以添 ...
- 1192: 零起点学算法99——The sum problem(C)
一.题目 http://acm.wust.edu.cn/problem.php?id=1192&soj=0 二.分析 要求从序列1,2,3,,,N,中截取一部分使他们的和为M 输入多组数据 输 ...
- LOJ6583 ICPC World Finals 2019何以伊名始(广义后缀自动机)
对trie建SAM,询问串倒过来跑到的节点的|right|即为答案. #include<bits/stdc++.h> using namespace std; #define ll lon ...