日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#利用反射将Datatable转化为指定实体类ListT

發(fā)布時(shí)間:2025/3/11 C# 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#利用反射将Datatable转化为指定实体类ListT 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景介紹

? ? ? ? ? 在軟件開發(fā)中肯定免不了和數(shù)據(jù)庫打交道,我們對數(shù)據(jù)的增刪改查最終會(huì)轉(zhuǎn)化為SQL在數(shù)據(jù)庫中執(zhí)行。從SQLServer中查出數(shù)據(jù)一般有兩種方式:一是ADO.NET直接寫SQL語句從數(shù)據(jù)中查出數(shù)據(jù),另一種是利用ORM框架得到數(shù)據(jù)。ADO.NET作為傳統(tǒng)的數(shù)據(jù)庫對接方式現(xiàn)在貌似已經(jīng)不怎么流行了。讓程序員直接寫SQL實(shí)現(xiàn)增刪改查功能存在一定和風(fēng)險(xiǎn)并且在程序中寫SQL非常不利于程序的擴(kuò)展和維護(hù),也不利于數(shù)據(jù)庫的維護(hù)和更換,極大的增加了程序的不穩(wěn)定性。

? ? ? ? ? 其二、利用傳統(tǒng)的ADO.NET Datatable的數(shù)據(jù)操作語法十分繁瑣,并且裝箱拆箱的效率十分低下,因此,對數(shù)據(jù)的操作應(yīng)該使用實(shí)體類。那么問題來了,對于那些由于各種原因還沒有利用起ORM框架,但是想利用實(shí)體類進(jìn)行數(shù)據(jù)操作的程序,我們只需要將Datatable中的數(shù)據(jù)轉(zhuǎn)化為實(shí)體類,便可實(shí)現(xiàn)。廢話不多說,代碼如下所示:

public static class DatatableExtension {/// <summary>/// 將Datatable轉(zhuǎn)化為指定實(shí)體類/// </summary>/// <typeparam name="T">實(shí)體類對象類型</typeparam>/// <param name="_sourceTable">源DataTable</param>/// <returns>返回轉(zhuǎn)化后的DataTable</returns>public static List<T> ToList<T>(this DataTable _sourceTable) where T : new(){var resultLists = new List<T>();var pi = typeof(T).GetProperties(BindingFlags.Public|BindingFlags.Instance|BindingFlags.DeclaredOnly).ToList();if (_sourceTable == null || pi == null || pi.Count == 0){//DataTable為null或?qū)嶓w類無屬性則返回空的實(shí)體類}else{var wildColumnsLists = new List<string>();//用于存放無法找到對應(yīng)實(shí)體類屬性的列,無后續(xù)操作var piFlagLists = new List<Tuple<PropertyInfo, bool>>();//用于存放找到對應(yīng)實(shí)體類屬性的列,二元組T1是列的數(shù)據(jù)類型,T2是類型是否和實(shí)體類是否相等foreach (DataColumn col in _sourceTable.Columns){if (pi.Exists(p => p.Name.Equals(col.ColumnName))){var prop = pi.FirstOrDefault(q => q.Name.Equals(col.ColumnName));piFlagLists.Add(Tuple.Create(prop, prop.PropertyType.Equals(col.DataType)));}else{wildColumnsLists.Add(col.ColumnName);}}foreach (DataRow dr in _sourceTable.Rows){T targetEntity = new T();foreach (var piFlag in piFlagLists){if (piFlag.Item1.SetMethod != null && !piFlag.Item1.PropertyType.IsGenericType && !dr.IsNull(piFlag.Item1.Name)){//賦值操作,如類型不相同則以實(shí)體類為準(zhǔn)并賦值piFlag.Item1.SetValue(targetEntity, piFlag.Item2 ? dr[piFlag.Item1.Name] : Convert.ChangeType(dr[piFlag.Item1.Name], piFlag.Item1.PropertyType));}else{//無法賦值的情況:1、set訪問器不存在2、此屬性為泛型3、Datatable中招不到需要轉(zhuǎn)換的列名}}resultLists.Add(targetEntity);}}return resultLists;}/// <summary>/// 將篩選后的Datatable轉(zhuǎn)化為指定實(shí)體類/// </summary>/// <typeparam name="T"></typeparam>/// <param name="_sourceTable">源DataTable</param>/// <param name="_predicate">執(zhí)行篩選的委托</param>/// <returns>返回執(zhí)行篩選轉(zhuǎn)化后的DatatTable</returns>public static List<T> ToList<T>(this DataTable _sourceTable, Func<DataRow, bool> _predicate) where T : new(){var whereDT = _sourceTable.Where(_predicate);return whereDT.ToList<T>();}/// <summary>/// 在Datatable中使用Where方法進(jìn)行篩選/// </summary>/// <param name="_sourceTable">源DataTable</param>/// <param name="_whereFunc">執(zhí)行篩選的委托</param>/// <returns>篩選后的DataTable</returns>public static DataTable Where(this DataTable _sourceTable, Func<DataRow, bool> _predicate){if (_sourceTable == null){throw new ArgumentNullException(nameof(_sourceTable));}else{if (_predicate == null){return _sourceTable;}else{var rowLists = _sourceTable.AsEnumerable().Where(_predicate);var resultDataTable = rowLists.Count() == 0 ? _sourceTable.Clone() : rowLists.CopyToDataTable();return resultDataTable;}}}/// <summary>/// 在Datatable中調(diào)用Select方法進(jìn)行選取/// </summary>/// <typeparam name="T">選取結(jié)果類型</typeparam>/// <param name="_sourceTable">源Datatable</param>/// <param name="_selector">執(zhí)行委托</param>/// <returns></returns>public static List<T> Select<T>(this DataTable _sourceTable, Func<DataRow, T> _selector){if (_sourceTable == null){throw new ArgumentNullException(nameof(_sourceTable));}else{if (_selector == null){throw new ArgumentNullException(nameof(_sourceTable));}else{var resultLsit = _sourceTable.AsEnumerable().Select(_selector).ToList();return resultLsit;}}}/// <summary>/// 直接在當(dāng)前DataTable對象上調(diào)用Any方法進(jìn)行判斷/// </summary>/// <param name="_dt">當(dāng)前DataTable變量</param>/// <param name="_anyFunc">執(zhí)行Any方法的委托</param>/// <returns>結(jié)果,true:代表有元素滿足條件,false :代表沒有元素滿足條件</returns>public static bool Any(this DataTable _dt, Func<DataRow, bool> _predicate){if (null != _dt && null != _predicate){var reuslt = _dt.AsEnumerable().Any(_predicate);return reuslt;}else{throw new ArgumentNullException(string.Format("{0}|{1}", null == _dt ? nameof(_dt) : string.Empty, null == _predicate ? nameof(_predicate) : string.Empty));}}/// <summary>/// DataTable的ForEach擴(kuò)展方法/// </summary>/// <param name="_dt">當(dāng)前dt</param>/// <param name="_action">要執(zhí)行的委托</param>public static void ForEach(this DataTable _dt, Action<DataRow> _action){if (null == _dt){throw new ArgumentNullException(nameof(_dt));}if (null == _action){throw new ArgumentNullException(nameof(_action));}_dt.AsEnumerable().ToList().ForEach(row => _action(row));}/// <summary>/// 獲取當(dāng)前DataTable對象的滿足委托條件的第一個(gè)datarow/// </summary>/// <param name="_dt"></param>/// <param name="_predicate"></param>/// <returns></returns>public static DataRow FirstOrDefault(this DataTable _dt, Func<DataRow, bool> _predicate){if (null == _predicate){throw new ArgumentNullException(nameof(_predicate));}return _dt.AsEnumerable().FirstOrDefault(_predicate);}/// <summary>/// 獲取當(dāng)前DataTable對象的滿足委托條件最后一個(gè)datarow/// </summary>/// <param name="_dt"></param>/// <param name="_predicate"></param>/// <returns></returns>public static DataRow LastOrDefault(this DataTable _dt, Func<DataRow, bool> _predicate){if (null == _predicate){throw new ArgumentNullException(nameof(_predicate));}return _dt.AsEnumerable().LastOrDefault(_predicate);} }

?在DatatableExtension類中,前兩個(gè)兩個(gè)擴(kuò)展方法;一個(gè)是方法直接將Datatable轉(zhuǎn)化為指定的實(shí)體類,第二個(gè)方法支持將Datatable進(jìn)行委托篩選后轉(zhuǎn)化為指定實(shí)體類,操作代碼如下圖所示:

string sql = string.Format(@"SELECT A.UserID ,A.UserName ,A.UserPwd ,FROM dbo.TabUsers AS A "); DataSet ds = dbhelp.JustGetData(sql);//查詢出sql語句對應(yīng)的數(shù)據(jù) List<TabUser> UserLists = ds.Tables[0].ToList<TabUser>();//將DataTable轉(zhuǎn)化為TabUser實(shí)體類 List<TabUser> easyUserLists = ds.Tables[0].ToList<TabUser>(p => p["UserName"].ToString().Contains("車間"));//篩選出UserName包含“車間”字段的數(shù)據(jù)public class TabUser:EntityBase {public string UserName { get; set; }public string UserPwd { get; set; }public long UserID { get; set; } }

?

總結(jié)

以上是生活随笔為你收集整理的C#利用反射将Datatable转化为指定实体类ListT的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。