4

状況

多くのパラメーター化された SQL コマンドがあります。これらのコマンドをループ内で次々に実行すると、次のようになります。

public void SaveChanges()
{
    using (var ts = _Context.Database.BeginTransaction())
    {
        try
        {
            _Context.SaveChanges();

            foreach (var cmd in _Commands)
            {
                if (cmd.Parameter != null)
                {
                    _Context.Database.ExecuteSqlCommand(cmd.Sql, cmd.Parameter.ToArray()); 
                }
            }

            ts.Commit();
        }
        catch (Exception ex)
        {
            ts.Rollback();
            throw new Exception("SaveChanges");
        }
    }
}

上記のコードは機能し、トランザクションのロールバックも期待どおりに機能します。

私のコマンドクラスは次のようになります。

public class SqlBuilderCommand
{
    public string Sql { get; set; }

    public List<SqlParameter>  Parameter {get;set;}
}

具体的な解決策がない重複の可能性

この質問と重複する可能性のあるものをいくつか見つけました。最も近いものはこれです:

重複の可能性 1

残念ながら、Entity Framework では役に立ちません (または理解できないだけです)。

質問

  1. リスト内のすべてのコマンドを 1 回の往復で実行できますか?

  2. そうでない場合、ADO.NET で可能ですか?

解決策と欠点/制限

正しい答えをくれた@Evgeniに感謝します。はい、多くのSQL文字列を連結して、パラメーターを1回の往復でリストとして送信するだけです。それは素晴らしいことです。

ただし、SQL-Server には制限があります。SQL-Server は、1 つのコマンドで最大 2100 個のパラメーターのみを受け入れます。したがって、7 つのデータベース列を持つオブジェクトがある場合、一括挿入の最大数はコマンドごとに 300 オブジェクトです。そうしないと、例外が発生します。

5000 個のオブジェクトに対してこれを行うと、17 個の一括挿入 (5000/300) が発生します。5000 個のオブジェクトの時間を停止しましたが、それでも 8 ~ 9 秒であり、これは遅すぎます。生の SQL の方がはるかに高速であることがわかっているからです。

この時点で、SQL コマンドを高速化する方法があると誰かに言われない限り、生の SQL を回避する方法はないと思います。

多分私はこれにフォローアップの質問を書きます. くそ。

4

1 に答える 1