3

私は次のようにストアドプロシージャを持っています:

CREATE PROCEDURE GetMultipleResults
   @SomeID int
AS
BEGIN
   SELECT * FROM SomeTable1 where SomeColumn1 = @SomeID
   SELECT * FROM SomeTable2 where SomeColumn2 = @SomeID
   SELECT * FROM SomeTable3 where SomeColumn3 = @SomeID
   SELECT * FROM SomeTable4 where SomeColumn4 = @SomeID
END

次に、次のコードを使用してデータを実行および取得します。

[Function(Name = "dbo.SPROCName")]
[ResultType(typeof(ResultSet1))]
[ResultType(typeof(ResultSet2))]
[ResultType(typeof(ResultSet3))]
[ResultType(typeof(ResultSet4))]
public IMultipleResults SomeMethod([Parameter(DbType = "INT")] int? SomeID
{
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), SomeID);
    return ((IMultipleResults)(result.ReturnValue));
}

最後に、それぞれの結果を取得するために、次のようなものを実行します。

public void SomeOtherMethod(int SomeID)
{
    DataContext1 context = new DataContext1 (dbConnString);
    IMultipleResults results = context.SomeMethod(SomeID);

    ResultSet1 resultSet1= results.GetResult().FirstOrDefault();
    IEnumerable resultSet2 = results.GetResult().ToList();
    IEnumerable resultSet3 = results.GetResult().ToList();
    ResultSet4 resultSet4= results.GetResult().FirstOrDefault();
}

私の質問は、Linq-to-SQLがストアドプロシージャ全体を1回実行しGetResult()てから、それを使用してメモリから取得するのか、それともn個のクエリ(ラウンドトリップdb呼び出し)を実行するのかということです。ここで、nはストアドプロシージャ内のselectステートメントの数です。 proc(この例では4)?

私が尋ねている理由は、次の行は、大きなデータの場合でも実行にほぼ同じ時間がかかるためです。

IMultipleResults results = context.SomeMethod(SomeID);

ただし、resultSet3が大量のデータである場合、次の部分を実行すると、かなりの時間がかかります。

IEnumerable resultSet3 = results.GetResult().ToList();
4

1 に答える 1

4

確かに、データベースへのラウンドトリップは1回だけです。LinqToSQLは、適用したResultType属性が正しいことに依存する必要がある、ストアドプロシージャ内の内容を認識できません。

内部的には、LinqToSQLはストアドプロシージャを実行し、データリーダーを開いて結果を取得します。

場合FirstOrDefaultによっては、最初の項目(存在する場合)を取得してから、IDataReader.NextResultを使用して次の結果セットにスキップします。したがって、resultSet1が潜在的に大きい場合でも、最初の行のみをネットワーク経由でフェッチする必要があります。

場合ToListによっては、結果セット全体がリーダーによって取得されます。したがって、データが多い場合は、必然的に時間がかかります。

于 2013-03-06T08:35:01.737 に答える