EF Coreは動的クエリと複数のコンテキストインスタンスプールへのEF Core注入を実装します。

EF Coreは動的クエリと複数のコンテキストインスタンスプールへのEF Core注入を実装します。

EF 6.xとEF Coreの両方で生のクエリに対するAPiを比較する

最后更新 2022/05/04 16:43
Jeffcky
预计阅读 3 分钟
分类
EF Core
标签
.NET C# EF Core ORM

前のページ

長い間ブログを書いていない、今日は記事を追加して、時折ブログを書く気がない、時間がかかりますが、まだ主張している、結局のところ、書かれたものはいくつかの子供の靴を助けることができます、次に私たちはまっすぐにトピックに向かいます。EF 6.xでもEF Coreでも、元のクエリのAPiでも、単一の値をクエリしたいだけなので、サポートされていません。例えば、いくつかの列しか必要ないので、サポートされていません。サポートされていないのが多すぎます。唯一のサポートは、テーブル内のすべての列、すなわちクラス内のすべてのフィールドを返すことです。だから、ほとんどの場合、私はネイティブSQLを書いている、元のクエリはあまり使用されていない、最近、EFを愛するピアがSqlQueryを使用して動的クエリを実装する方法を尋ねた、私は答えがない、この方法を使用するとは思わなかった、プライベートで見て、または少し考えてください。それがあなたに役立つなら、私はブログを追加したと考えてください。

EF 6.xとEF Coreが動的クエリを実装

public static IEnumerable<dynamic> SqlQueryDynamic(this DbContext db, string Sql, params SqlParameter[] parameters)
{
    using (var cmd = db.Database.Connection.CreateCommand())
    {
        cmd.CommandText = Sql;

        if (cmd.Connection.State != ConnectionState.Open)
        {
            cmd.Connection.Open();
        }

        foreach (var p in parameters)
        {
            var dbParameter = cmd.CreateParameter();
            dbParameter.DbType = p.DbType;
            dbParameter.ParameterName = p.ParameterName;
            dbParameter.Value = p.Value;
            cmd.Parameters.Add(dbParameter);
        }

        using (var dataReader = cmd.ExecuteReader())
        {
            while (dataReader.Read())
            {
                var row = new ExpandoObject() as IDictionary<string, object>;
                for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++)
                {
                    row.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]);
                }
                yield return row;
            }
        }
    }
}

では、上記のクエリの後に動的コレクションが返された場合、コレクションオブジェクトに変換するにはどうすればよいでしょうか。最初にシリアライズしてからデシリアライズしたいとは思いませんが、より良いソリューションがあれば自分で実装してください。

using (var ctx = new EfDbContext())
{
    ctx.Database.Log = Console.WriteLine;

    var dynamicOrders = ctx.SqlQueryDynamic("select * from dbo.Orders");
    var ordersJson = JsonConvert.SerializeObject(dynamicOrders);
    var orders = JsonConvert.DeserializeObject<List<Order>>(ordersJson);
};

もちろん、私は単にテーブルをクエリしましたが、複数のテーブルがある場合は、最終的に異なるオブジェクトにデシリアライズすることができ、テストされていない場合は、自分でテストすることができます。

EF Coreでは複数のコンテキストインスタンスプールを使用

EF 6.xでもEF Coreでも、常に1つのコンテキストを使用している人はたくさんいますが、複数のコンテキストを使用することを考えたことはありますか?例えば、Eコマースプロジェクトでは、製品関連の操作には製品コンテキスト、ショッピングカートへの追加操作にはショッピングカートコンテキスト、注文操作には注文コンテキストを使用できます。そのメリットは何でしょうか。データベーステーブル、つまりエンティティを異なるビジネスに分割することができます。今まで誰もやったことがないし、私だったらやっていただろう。

//Add DbContext
var dbConnetionString = Configuration.GetConnectionString("DbConnection");
services.AddDbContextPool<ShopCartDbContext>(options =>
{
    options.UseSqlServer(dbConnetionString);
}).AddDbContextPool<BookDbContext>(options =>
{
    options.UseSqlServer(dbConnetionString);
}).AddDbContextPool<OrderDbContext>(options =>
{
    options.UseSqlServer(dbConnetionString);
});

EF Core 2.0にはADO.NETの接続プールに似たコンテキストインスタンスプールがありますが、表面的に理解すると、コンテキストインスタンスプール(昨年からEF 6.xとEF Coreに関する本を書き始め、最近出版される予定です)の実装の本質は、ADO.NETの接続プールと同じではないと言うことができます。上記のように、複数のコンテキストインスタンスプールを使用することは必ずしも便利ですか?申し訳ありませんが、この設定は間違っています。しかし、プログラムを実行すると、以下のような例外がスローされます。

Exception message:
System.ArgumentException: Expression of type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MultiContext.Contexts.BContext]' cannot be used for constructor parameter of type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MultiContext.Contexts.AContext]' Parameter name: arguments[0]
Stack trace:
...........

この機能が登場したとき、誰もがパフォーマンスの向上を歓迎しました。ごめんなさいコンテキストインスタンスプールはパフォーマンスをある程度向上させるかもしれませんが、私は可能なパフォーマンスの改善しか言えません。EF Coreのコンテキストインスタンスプール実装の原理を知っているか見たことがあれば、その実装の性質を理解し、潜在的なパフォーマンス改善の意味を理解するでしょう。複数のコンテキストインスタンスプールを登録できない理由については、私も個人的にプロジェクトを書いています。

https://github.com/aspnet/EntityFrameworkCore/issues/9433。

まとめまとめまとめ

さて、今日はここに来て、あまりにも多くの説明と物語がない、上にまっすぐなテーマ、最近の思考のリリースで、ブログを書くことに徐々に大きな関心を失って、時折感情的に、私は完全な血の復活と良い気分を待って、あなたと技術を共有し続ける、私は、しばらくの間、ブログを書いていない疲れているかもしれない、または個人的にIdentity Serverや他の技術を学ぶ、私たちの行を行う、転職しない限り、正直に経験を積み、技術を学びましょう。若くして戦わないで、いつ戦うのでしょうか。今日言ったことは、想像の中で、ごめんなさい。

あなたが見るのは物そのものではなく、解釈によって与えられた意味です。

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2022/06/02

EF Core 6の新機能概要(4)

この記事では、SQLite、インメモリプロバイダ、およびEF. Functions.Containsメソッドに対するEF Coreの改善点について説明します。

继续阅读
同分类 / 同标签 2022/06/02

EF Core 6の新機能概要(2)

前回の記事に続き、この記事では、バリューコンバータ、足場、Db Contextの改善など、EF Core 6の10の新機能を紹介します。

继续阅读