ホームページ  >  記事  >  バックエンド開発  >  .Net core上でSQL文を直接実行してDataTableを生成する実装方法

.Net core上でSQL文を直接実行してDataTableを生成する実装方法

高洛峰
高洛峰オリジナル
2016-12-20 14:24:062345ブラウズ

.net core は SQL ステートメントを実行できますが、生成できるのは厳密に型指定された戻り結果のみです。たとえば、var blogs = context.Blogs.FromSql("SELECT * FROM dbo.Blogs").ToList() のようになります。 DataSet や DataTable などの弱い型を返すことはできません。この理由により DataTable が .net core に実装されていない可能性がありますが、DataTable は引き続き使用される可能性があります。ここには、ユーザーが自分で SQL のようなステートメントを記述し、それを実行してテーブルに表示できるようにするデータ ウェアハウス要件があります。ステートメントは常に変化するため、ユーザーのステートメントが何を出力するかはわかりません。また、ステートメントを型で定義することもできないため、DataTable メソッドのみを使用できます。

以前は、.net Framework では、dataadapter を通じてデータテーブルに簡単にデータを入力でき、その後、データテーブルのデータをクライアントにプッシュして表示することができました。ただし、.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 を生成します。 .net Framework のコア スキル はい、このプロセスでは、SQL とパラメーターに基づいてネイティブ SQLCommand を作成し、ExecuteReader メソッドを実行して DataReader を返し、DataReader を MicroDataTable に書き込みます。 .net core の IConcurrencyDetector の説明は次のとおりです。この API は Entity Framework Core インフラストラクチャをサポートしており、コードから直接使用することを目的としていません。この API は将来のリリースで変更または削除される可能性があります。最初にこの方法で実装し、後で ef.core を変更できるか、より良い方法が提供できるかを確認することしかできません。

上記のプログラムでは、最後に MicroDataTableHelper.FillDataTable という文があります。このメソッドの主な機能は、DataReader から 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);
}
}

上記のプログラムは段階的に書かれているため、あまり効率的ではありません。最近時間がなく、元の Datatable の読み込みメソッドを分析していません。将来的には最適化する時間があります。

以下は、.net Framework を使用してデータリーダーからデータテーブルへのページング データを取得するプログラムです (参考のみ)。当時、このプログラムは table.beginloaddata/endloaddata メソッドを使用しており、効率が大幅に向上しました。

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;
}

上記は、.Net コアで SQL ステートメントを直接実行して DataTable を生成する方法をエディターが紹介したものです。皆さんのお役に立てれば幸いです。また、PHP 中国語 Web サイトをサポートしていただきありがとうございます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。