• <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下直接執行SQL語句并生成DataTable的實現方法

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

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

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

    .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,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

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

    文檔

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

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

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产AV国片精品有毛| 国产精品 日韩欧美| 国产精品99久久久久久猫咪| 欧美精品中文字幕亚洲专区| 久久亚洲中文字幕精品一区| 88国产精品无码一区二区三区| 国产精品无码久久综合| 亚洲中文字幕久久精品无码喷水| 久久精品中文字幕有码| 99热成人精品国产免男男| 国产成人精品免费视| 国产精品毛片一区二区三区| 亚洲AV无码久久精品蜜桃| 四虎国产精品永久在线看| 精品露脸国产偷人在视频| 99久久免费只有精品国产| 欧美一卡2卡3卡四卡海外精品| 99精品久久精品一区二区| 精品国产三级a在线观看| 人妻精品久久无码专区精东影业| 中文无码精品一区二区三区| 日韩一区二区三区精品| 久久亚洲中文字幕精品一区四 | 91精品国产自产在线观看| 99国产欧美精品久久久蜜芽| 久久国产热精品波多野结衣AV| 亚洲av永久无码精品表情包| 一本一本久久aa综合精品| 一本色道久久88精品综合| 日产精品一线二线三线芒果| 久久国产乱子伦免费精品| 亚洲国产精品无码中文字| 久久夜色精品国产噜噜亚洲AV| 亚洲精品无码久久千人斩| 亚洲欧洲久久久精品| 亚洲线精品一区二区三区影音先锋 | 国产精品 日韩欧美| 国产成人精品久久| 国产精品自在在线午夜福利| 国产午夜精品一区二区三区不卡 | 四虎国产精品免费久久5151|