亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > .NET > 正文

.Net core下直接執行SQL語句并生成DataTable的實現方法

2024-07-10 13:31:30
字體:
來源:轉載
供稿:網友

.net core可以執行SQL語句,但是只能生成強類型的返回結果。例如var blogs = context.Blogs.FromSql("SELECT * FROM dbo.Blogs").ToList()。而不允許返回DataSet、DataTable等弱類型??赡苡捎谶@個原因沒有實現在.net core中DataTable,然而DataTable還是可能會用到的。我們這里就有一個數據倉庫的需求,允許用戶自行編寫類似SQL語句,然后執行,以表格展示。因為語句是千變萬化的,因此我也不知道用戶的語句輸出的是啥,更無法以類型來定義,因此只能采用DataTable方式。

之前.net framework下,可以通過dataadpater很方便的填充datatable,然后將datatable的數據推送到客戶端展示。但是.net core下,已經沒有DataTable和DataSet,我們只能自行實現MicroDataTable。

這里我們也按照DataTable的方式,MicroDataTable的列定義為MicroDataColumn,行定義為MicroDataRow。代碼如下:

public class MicroDataTable{ /// <summary>/// 整個查詢語句結果的總條數,而非本DataTable的條數/// </summary>public int TotalCount { get; set; }public List<MicroDataColumn> Columns { get; set; } = new List<MicroDataColumn>();public List<MicroDataRow> Rows { get; set; } = new List<MicroDataRow>();public MicroDataColumn[] PrimaryKey { get; set; }public MicroDataRow NewRow(){return new MicroDataRow(this.Columns, new object[Columns.Count]);}}public class MicroDataColumn{public string ColumnName { get; set; }public Type ColumnType { get; set; }}public class MicroDataRow{private object[] _ItemArray;public List<MicroDataColumn> Columns { get; private set; }public MicroDataRow(List<MicroDataColumn> columns, object[] itemArray){this.Columns = columns;this._ItemArray = itemArray;}public object this[int index]{get { return _ItemArray[index]; }set { _ItemArray[index] = value; }}public object this[string columnName]{get{int i = 0;foreach (MicroDataColumn column in Columns){if (column.ColumnName == columnName)break;i++;}return _ItemArray[i];}set{int i = 0;foreach (MicroDataColumn column in Columns){if (column.ColumnName == columnName)break;i++;}_ItemArray[i] = value;}}}

需要注意的是TotalCount屬性,在分頁情況下,是指查詢語句在數據庫中查詢出的所有記錄條數,而MicroDataTable的數據是當前頁面的記錄。

對于從數據庫中獲取DataTable的做法,采用類似SqlHelper的方式編寫DbContext的ExecuteDataTable擴展方法,傳入SQL語句和SQL語句的參數,生成MicroDataTable:

public static MicroDataTable ExecuteDataTable(this DbContext context, string sql, params object[] parameters){var concurrencyDetector = context.Database.GetService<IConcurrencyDetector>();using (concurrencyDetector.EnterCriticalSection()){var rawSqlCommand = context.Database.GetService<IRawSqlCommandBuilder>().Build(sql, parameters);RelationalDataReader query = rawSqlCommand.RelationalCommand.ExecuteReader(context.Database.GetService<IRelationalConnection>(), parameterValues: rawSqlCommand.ParameterValues);return MicroDataTableHelper.FillDataTable(query.DbDataReader, 0, int.MaxValue);}}public static MicroDataTable ExecuteDataTable(this DbContext context, string sql, int pageIndex, int pageSize, params object[] parameters){var concurrencyDetector = context.Database.GetService<IConcurrencyDetector>();using (concurrencyDetector.EnterCriticalSection()){var rawSqlCommand = context.Database.GetService<IRawSqlCommandBuilder>().Build(sql, parameters);RelationalDataReader query = rawSqlCommand.RelationalCommand.ExecuteReader(context.Database.GetService<IRelationalConnection>(), parameterValues: rawSqlCommand.ParameterValues);return MicroDataTableHelper.FillDataTable(query.DbDataReader, 0, int.MaxValue);}}

這個方法還是需要部分.net framework core的技巧的,流程是根據SQL和參數創建原生的SQLCommand,執行ExecuteReader方法返回DataReader,再把DataReader填充到MicroDataTable中。注意的是,IConcurrencyDetector在.net core的描述是這樣的:This API supports the Entity Framework Core infrastructure and is not intended to be used directly from your code. This API may change or be removed in future releases。我們只能先這樣實現,以后看是否ef.core能否改變或者給出更好的方式。

上面程序中,最后有一句話MicroDataTableHelper.FillDataTable,這個方法的主要功能是從DataReader填充到MicroDataTable的。

public static MicroDataTable FillDataTable(DbDataReader reader, int pageIndex, int pageSize){bool defined = false;MicroDataTable table = new MicroDataTable();int index = 0;int beginIndex = pageSize * pageIndex;int endIndex = pageSize * (pageIndex + 1) - 1;while (reader.Read()){object[] values = new object[reader.FieldCount];if (!defined){for (int i = 0; i < reader.FieldCount; i++){MicroDataColumn column = new MicroDataColumn(){ColumnName = reader.GetName(i),ColumnType = reader.GetFieldType(i)};table.Columns.Add(column);}defined = true;}if (index >= beginIndex && index <= endIndex){reader.GetValues(values);table.Rows.Add(new MicroDataRow(table.Columns, values));}index++;}table.TotalCount = index;return table;}

上面這個程序,是按部就班的寫法,效率應該不太高。最近時間緊,沒有分析原先的Datatable裝載方式,以后有時間優化吧。

下面給出一個當時用.net framework從datareader獲取分頁數據到datatable的程序,僅作參考。當時這段程序使用了table.beginloaddata/endloaddata方式,效率明顯有提升。

using (IDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)){int fieldCount = reader.FieldCount;for (int i = 0; i < fieldCount; i++){table.Columns.Add(reader.GetName(i), reader.GetFieldType(i));}object[] values = new object[fieldCount];int currentIndex = 0;int startIndex = pageSize * pageIndex;try{table.BeginLoadData();while (reader.Read()){if (startIndex > currentIndex++)continue;if (pageSize > 0 && (currentIndex - startIndex) > pageSize)break;reader.GetValues(values);table.LoadDataRow(values, true);}}finally{table.EndLoadData();try //lgy:由于連接阿里云ADS數據庫cmd.Cancel()會報錯,所以把錯誤忽略了。{cmd.Cancel();}catch { }reader.Close();}}

以上所述是小編給大家介紹的.Net core下直接執行SQL語句并生成DataTable,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到ASP.NET教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品视频在线观看| 亚洲成人a级网| 欧美伊久线香蕉线新在线| 国产精品久久久91| 亚洲加勒比久久88色综合| 最近更新的2019中文字幕| 国产精品爽爽ⅴa在线观看| 欧美—级高清免费播放| 97久久精品在线| 国产精品中文久久久久久久| 欧美乱大交xxxxx| 91国自产精品中文字幕亚洲| 日韩大片在线观看视频| 91影视免费在线观看| 日韩www在线| 国产精品成人品| 欧美午夜无遮挡| 中文字幕亚洲字幕| 久久人人爽人人爽人人片亚洲| 97av在线视频免费播放| 最近2019年日本中文免费字幕| 亚洲精品xxx| 欧美日韩中国免费专区在线看| 成人国产精品日本在线| 亚洲性视频网址| 午夜精品三级视频福利| 国产亚洲成av人片在线观看桃| 久久久久久久999精品视频| 综合激情国产一区| 国产精品mp4| 亚洲国产成人av在线| 午夜精品一区二区三区在线视| 亚洲老头老太hd| 亚洲精品一区二区三区不| 中文字幕日本精品| 91久久夜色精品国产网站| 欧美激情国产精品| 国产成人一区二区在线| 欧美大人香蕉在线| 一区二区三区美女xx视频| 96pao国产成视频永久免费| 午夜精品久久久久久99热软件| 国产精品国产三级国产aⅴ浪潮| 久久久在线免费观看| 91久久久久久| 国产精品老女人精品视频| 国产成人精品av在线| 国产精品视频白浆免费视频| 亚洲福利影片在线| 国产一级揄自揄精品视频| 欧美性20hd另类| 91精品久久久久久久久久另类| 永久免费看mv网站入口亚洲| 久久91精品国产91久久久| 这里只有精品丝袜| 久久久久久91| 亚洲欧洲一区二区三区在线观看| 亚洲国产欧美在线成人app| 国产亚洲精品久久久久久777| 亚洲欧美中文日韩在线| 久久久噜噜噜久久中文字免| 精品高清一区二区三区| 91日本视频在线| 亚洲欧美日韩高清| 永久免费看mv网站入口亚洲| 粉嫩老牛aⅴ一区二区三区| 欧美又大又硬又粗bbbbb| 欧美一区二区三区……| 亚洲一区二区日本| 91精品在线看| 中文字幕亚洲一区在线观看| 浅井舞香一区二区| 亚洲国产精品va在线看黑人动漫| 亚洲第一视频网| 国内精品国产三级国产在线专| 91沈先生在线观看| 欧美日韩xxxxx| 久久久91精品| 人人爽久久涩噜噜噜网站| 久久国产精品免费视频| 亚洲一区二区自拍| 亚洲网址你懂得| 97视频在线观看播放| 亚洲国产成人av在线| 91精品国产高清久久久久久91| 亚洲性xxxx| 一区二区三区四区在线观看视频| 日韩av在线免费观看一区| 亚洲欧美激情四射在线日| 欧美日韩成人精品| 亚洲天堂av综合网| 亚洲国产精品大全| 欧美性生交xxxxxdddd| 欧美日韩国产综合新一区| 国产日韩av高清| 久久激情视频免费观看| 欧美高清视频在线播放| 日本高清视频一区| 国产亚洲精品美女久久久久| 国产精品草莓在线免费观看| 国产精品96久久久久久| 国产亚洲精品美女久久久久| 欧美激情欧美激情| 国产日韩精品在线| 一区二区日韩精品| 国产精品日韩在线观看| 久久99精品视频一区97| 亚洲女人天堂成人av在线| 日韩高清中文字幕| 欧美色另类天堂2015| 欧美色另类天堂2015| 精品久久久久久久久中文字幕| 中文国产亚洲喷潮| 日韩欧美一区视频| 一区二区国产精品视频| 中文字幕亚洲字幕| 久久久国产在线视频| 91精品国产99久久久久久| 九九久久精品一区| 亚洲自拍在线观看| 国产精品久久久久久久久借妻| 久久成人精品一区二区三区| 91高潮精品免费porn| 狠狠色噜噜狠狠狠狠97| 日韩电影中文 亚洲精品乱码| 97人人做人人爱| 欧美高清视频在线观看| 91国内揄拍国内精品对白| 亚洲毛片在线免费观看| 成人在线小视频| 97视频在线免费观看| 91在线免费看网站| 欧美日本在线视频中文字字幕| 国产成人亚洲综合91| 久久精品中文字幕一区| 午夜免费久久久久| 国产日韩视频在线观看| 国产日韩视频在线观看| 久久久久久国产精品三级玉女聊斋| 97超级碰碰碰| 色偷偷偷综合中文字幕;dd| 亚洲一区二区三区四区在线播放| 青青在线视频一区二区三区| 欧美午夜www高清视频| 久久久久久美女| 国内伊人久久久久久网站视频| 国产精品无av码在线观看| 亚洲人成自拍网站| 最近2019年中文视频免费在线观看| 亚洲剧情一区二区| 成人网中文字幕| 日韩av影院在线观看| 国产精品高潮在线| 成人精品一区二区三区电影黑人| 欧美激情乱人伦| 久久精品99久久久香蕉| 欧美激情网站在线观看| 久久久久久久久国产精品| 91成人国产在线观看| 精品久久久久国产| 国产亚洲美女精品久久久| 91精品国产色综合久久不卡98| 久久精品国产亚洲| 欧美一级电影免费在线观看|