1

ユーザーの情報、セキュリティ、部門、およびその他のいくつかの情報テーブルを複製して、同じ設定で新しいユーザーを作成しています。この情報は、複数の DGV を通じて表示されています。コンテキストに通常の linq を使用する場合:

var x = (from ctx in context.UserInfo
         where ctx.UserID == userID
         select ctx);

情報はほぼ瞬時に表示されますが、SaveChanges()私がやろうとしていることを呼び出さない限り、追加されたユーザーは表示されません。

次に、ローカル linq の使用に切り替えました。

context.UserInfo.Load();
var x = (from ctx in context.UserInfo.Local
         where ctx.UserID == userID
         select ctx);

ただし、クエリを実行しているいくつかのテーブルには 30,000 を超えるエントリがあり、.Local 呼び出しによって情報を表示するプロセスが大幅に遅くなります。私が調査したところ、これは検証追跡が原因で発生します。

次に、変更トラッカーを使用してみました。

context.UserInfo.Load();
var x = (from ctx in context.ChangeTracker.Entries<UserInfo>()
         where ctx.Entity.UserID == userID && ctx.State == EntityState.Unchanged ||
            ctx.State == Entity.State.Added || ctx.State == EntityState.Modified
         select ctx.Entity)

これにより、ローカル呼び出しと同じようにパフォーマンスが低下しました。

Localを呼び出さずに追加されたオブジェクトをすばやく表示し、削除されたオブジェクトを表示しない方法はありますか、またはLocalを高速化する方法はありますか?

私はかなりの量の調査を行い、この問題に数日間取り組み、自分で理解しようとしましたが、今はぐるぐる回っています.

変更が行われる前に、コンテキストのコピーを作成することを考えました。変更が発生したときに保存し、ユーザーが複製されたユーザーの作成をキャンセルすることを決定した場合は、元のコンテキストを呼び出して保存し、元のコンテキストを復元しますが、それは最後の手段と考えます。

プロジェクトは、Windows フォーム上の C# .net 4.5 および Entity Framework 5.0 で行われています。

編集:

クエリの実装方法に関するコードをさらに提供するには、次のようにします。

使用するデータを初期化する loadData() メソッドがあります。

public void loadData()
{
    var x = (from ctx in context.UserInfo
             select ctx).ToList();
}

これは上記のコードと同じことをすると思います

public void loadData()
{
    context.UserInfo.load();
}

次に、クエリが呼び出されます。これは高速なクエリですが、コンテキストの変更は表示されません

public List<UserInfo> getUserInfo()
{
    var user = (from ctx in context.UserInfo
                where ctx.UserID == userID
                select ctx).ToList();

    return user;
}

このクエリは遅いですが、変化を示しています

public List<UserInfo> getUserInfo()
{
    var user = (from ctx in context.UserInfo.Local
                where ctx.UserID == userID
                select ctx).ToList();

    return user;
}
4

2 に答える 2

1

私はここでロングショットに行きます - 遅延はEFがモデルキャッシュの初期化に持っている標準的な遅延よりも短いと思います. 詳細については、この質問に対する私の回答を参照してください。確実に確認するには、コードを変更する必要があります...

于 2013-06-18T17:30:48.437 に答える
0

もともと、ToList() が Load() と同じように動作することを知りませんでした。これにより、loadData() メソッドを使用しないようにコードを変更し、必要な情報の一部のみを初期化しました。

public List<UserInfo>(int userID 1)
{
    var data = (from ctx in context.UserInfo
                where ctx.UserID == userID
                select ctx).ToList();

    List<UserInfo> user = (from ctx in context.UserInfo.Local
                           where ctx.UserID == userID
                           select ctx).ToList();

    return user;
}

この変更により、クエリをほぼ瞬時に実行し、コンテキスト内で追加/削除/変更を追跡できるようになりました。このメソッドで見られる唯一の欠点は、多くのオブジェクトが UserInfo.Local にロードされると速度が低下し始めることですが、私の場合はほとんど発生しません。

于 2013-06-18T21:27:38.557 に答える