1

私の WCF サービスのビジネス ロジックでは、エンティティを見つける必要があるほとんどの場所で、次の構文を使用します。

public void UpdateUser(Guid userId, String notes)
{
    using (ProjEntities entities = new ProjEntities())
    {
          User currUser = entities.SingleOrDefault(us => us.Id == userId);
          if (currUser == null)
               throw new Exception("User with ID " + userId + " was not found");
    }
}

DbContext私は最近、 にメソッドがあることを発見しましたFind。これができるようになったことを理解しています。

public void UpdateUser(Guid userId, String notes)
{
    using (ProjEntities entities = new ProjEntities())
    {
          User currUser = entities.Find(userId);
          if (currUser == null)
               throw new Exception("User with ID " + userId + " was not found");
    }
}

注 : 「userId」プロパティは、テーブルの主キーです。

メソッドエンティティフレームワークを使用Findすると、エンティティが既にローカルメモリにあるかどうかを最初に確認し、そうであればそこから取得することを読みました。それ以外の場合 - データベースへのトリップが行われます (SingleOrDefault常にデータベースへのトリップが行われます)。

危険の可能性はありますSingleOrDefaultか?Find

Findデータベースではなくメモリからデータをフェッチする場合、更新されていない古いデータを取得できる可能性はありますか?

メモリ内にユーザーがいて、誰かがデータベース内のユーザーを変更した場合はどうなりますか? データベースから最新の更新されたレプリカを常にフェッチするのではなく、常にこの「メモリ」レプリカを使用すると問題になりませんか?

4

1 に答える 1

0

Find を使用して、データベースではなくメモリからデータを取得すると、更新されていない古いデータを取得できる可能性はありますか?

ここであなた自身の質問に答えたと思います。はい、使用Findすると、コンテキストにローカル コピーがあるため、データベースと同期していないエンティティが返される可能性があります。

特定のアプリケーションについて詳しく知らずに、これ以上言えることはありません。コンテキストを長期間維持しますか?それとも、コンテキストを開いて更新し、閉じますか? 明らかに、コンテキストを保持する時間が長ければ長いほど、最新のエンティティを取得する可能性が高くなります。

これに対処するための 2 つの戦略を考えることができます。1 つ目は上記のとおりです。コンテキストを開き、必要なことを行ってから破棄します。

using (var ctx = new MyContext())
{
    var entity = ctx.EntitySet.Find(123);
    // Do something with your entity here...
    ctx.SaveChanges();
}

次に、エンティティのDbEntityEntryGetDatabaseValuesを取得し、メソッドを使用してデータベースの値で更新できます。このようなもの:

var entity = ctx.EntitySet.Find(123);

// This could be a cached version so ensure it is up to date.
var entry = ctx.Entry(entity);
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
于 2013-05-09T20:29:57.223 に答える