網站首頁 編程語言 正文
一、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)設置字段值
Set?Field:為 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));
原文鏈接:https://www.cnblogs.com/springsnow/p/9433933.html
相關推薦
- 2023-07-15 express 連接 MongoDb
- 2024-03-13 微信小程序登錄接口 偶發性 解密錯誤
- 2022-10-12 sql中exists的基本用法示例_MsSql
- 2022-09-16 JQuery實現電梯導航效果_jquery
- 2022-08-11 python實現對excel中需要的數據的單元格填充顏色_python
- 2022-09-29 Kotlin協程launch原理詳解_Android
- 2022-07-07 詳解Git?的?rebase?命令使用方法_相關技巧
- 2022-12-21 Python?eval()和exec()函數使用詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支