.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 サイトをサポートしていただきありがとうございます。