• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    .Net core下直接執(zhí)行SQL語句并生成DataTable的實現(xiàn)方法

    來源:懂視網 責編:小采 時間:2020-11-27 22:36:25
    文檔

    .Net core下直接執(zhí)行SQL語句并生成DataTable的實現(xiàn)方法

    .Net core下直接執(zhí)行SQL語句并生成DataTable的實現(xiàn)方法:.net core可以執(zhí)行SQL語句,但是只能生成強類型的返回結果。例如var blogs = context.Blogs.FromSql(SELECT * FROM dbo.Blogs).ToList()。而不允許返回DataSet、DataTable等弱類型??赡苡捎谶@個原因沒有實現(xiàn)在.net core中DataTab
    推薦度:
    導讀.Net core下直接執(zhí)行SQL語句并生成DataTable的實現(xiàn)方法:.net core可以執(zhí)行SQL語句,但是只能生成強類型的返回結果。例如var blogs = context.Blogs.FromSql(SELECT * FROM dbo.Blogs).ToList()。而不允許返回DataSet、DataTable等弱類型??赡苡捎谶@個原因沒有實現(xiàn)在.net core中DataTab

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

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

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

    public class MicroDataTable
    { /// <summary>
    /// 整個查詢語句結果的總條數(shù),而非本DataTable的條數(shù)
    /// </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屬性,在分頁情況下,是指查詢語句在數(shù)據(jù)庫中查詢出的所有記錄條數(shù),而MicroDataTable的數(shù)據(jù)是當前頁面的記錄。

    對于從數(shù)據(jù)庫中獲取DataTable的做法,采用類似SqlHelper的方式編寫DbContext的ExecuteDataTable擴展方法,傳入SQL語句和SQL語句的參數(shù),生成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的技巧的,流程是根據(jù)SQL和參數(shù)創(chuàng)建原生的SQLCommand,執(zhí)行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。我們只能先這樣實現(xiàn),以后看是否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裝載方式,以后有時間優(yōu)化吧。

    下面給出一個當時用.net framework從datareader獲取分頁數(shù)據(jù)到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數(shù)據(jù)庫cmd.Cancel()會報錯,所以把錯誤忽略了。
    {
    cmd.Cancel();
    }
    catch 
    { 
    }
    reader.Close();
    }
    }

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

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    .Net core下直接執(zhí)行SQL語句并生成DataTable的實現(xiàn)方法

    .Net core下直接執(zhí)行SQL語句并生成DataTable的實現(xiàn)方法:.net core可以執(zhí)行SQL語句,但是只能生成強類型的返回結果。例如var blogs = context.Blogs.FromSql(SELECT * FROM dbo.Blogs).ToList()。而不允許返回DataSet、DataTable等弱類型??赡苡捎谶@個原因沒有實現(xiàn)在.net core中DataTab
    推薦度:
    標簽: 生成 sql net
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 人人妻人人澡人人爽人人精品97 | 国产精品九九九| 日本精品自产拍在线观看中文| 国产精品视频一区二区三区| 亚洲av无码国产精品色午夜字幕| 国产成人精品免费视频大全| 国产精品熟女高潮视频| 亚洲精品黄色视频在线观看免费资源| 88国产精品欧美一区二区三区| 精品无码AV无码免费专区| 亚洲精品无码99在线观看| 精品人妻伦九区久久AAA片69| 久久福利青草精品资源站| 精品人妻无码一区二区色欲产成人| 亚洲а∨天堂久久精品9966| 在线电影国产精品| 国产精品影音先锋| 99久久久国产精品免费无卡顿| 亚洲精品色午夜无码专区日韩| 久久亚洲精品无码播放| 国产精品麻豆入口| 成人国产精品一区二区视频| 天天爽夜夜爽精品视频app| 国产精品成人va| laowang在线精品视频| 精品无码人妻一区二区三区| 无码国产精品一区二区免费模式| 无码精品蜜桃一区二区三区WW | 亚洲精品无码不卡| 九九在线精品视频专区| 97r久久精品国产99国产精| 国产三级精品三级在线专区1| 久久亚洲精品中文字幕| 久久国产精品99国产精| 狼色精品人妻在线视频| 麻豆亚洲AV永久无码精品久久| 亚洲AV永久无码精品| 亚洲精品tv久久久久久久久| 亚洲午夜精品一级在线播放放| 亚洲午夜精品一级在线播放放 | 成人国产精品秘 果冻传媒在线|