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

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

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


View Code


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


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


復(fù)制代碼
1publicstaticMicroDataTable ExecuteDataTable(thisDbContext context,stringsql,paramsobject[] parameters)2{3varconcurrencyDetector = context.Database.GetService();45using(concurrencyDetector.EnterCriticalSection())6{7varrawSqlCommand = context.Database.GetService().Build(sql, parameters);89RelationalDataReader query = rawSqlCommand.RelationalCommand.ExecuteReader(context.Database.GetService(), parameterValues: rawSqlCommand.ParameterValues);1011returnMicroDataTableHelper.FillDataTable(query.DbDataReader,0,int.MaxValue);12}13}1415publicstaticMicroDataTable ExecuteDataTable(thisDbContext context,stringsql,intpageIndex,intpageSize,paramsobject[] parameters)16{17varconcurrencyDetector = context.Database.GetService();1819using(concurrencyDetector.EnterCriticalSection())20{21varrawSqlCommand = context.Database.GetService().Build(sql, parameters);2223RelationalDataReader query = rawSqlCommand.RelationalCommand.ExecuteReader(context.Database.GetService(), parameterValues: rawSqlCommand.ParameterValues);2425returnMicroDataTableHelper.FillDataTable(query.DbDataReader,0,int.MaxValue);26}27}
復(fù)制代碼


這個方法還是需要部分.net framework core的技巧的,流程是根據(jù)SQL和參數(shù)創(chuàng)建原生的SQLCommand,執(zhí)行ExecuteReader方法返回DataReader,再把DataReader填充到MicroDataTable中。注意的是,IConcurrencyDetector在.net core的描述是這樣的:Thi