2

次のコードを検討してください。

// check record exists

Adjuster adj = new Adjuster();

if (db.Adjusters.Where(x => x.userID == user.id).Any())
{
    adj = db.Adjusters.Where(x => x.userID == user.id).FirstOrDefault();
}
else
{
    // create adjuster record
    adj.id = Guid.NewGuid();
    adj.userID = user.id;

    db.Adjusters.InsertOnSubmit(adj);
}

.Any()最初に を呼び出し、次に を呼び出す方法に注意してください.FirstOrDefault()。これは、データベースに対する 2 つの別個のクエリになりますよね? これを1つだけに制限するにはどうすればよいですか?

ここで、次のコードを検討してください。

adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;

db.SubmitChanges();

LINQ/EF を使用して、相互に関係を持つさまざまなエンティティにアクセスできます。しかし、これを行うたびに、データベースへの複数の呼び出しが発生しませんか? たとえば、これら 3 つのすべてがデータベースへの別個の呼び出しですか?

adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;

これをデータベースへの単一の呼び出しに制限するにはどうすればよいですか? 唯一の方法は、次のようにオブジェクトをインスタンス化することだと思います。

SomeEntity obj = user.SomeEntity;

そして、次のようにプロパティを呼び出します。

adj.isPropertyAdjuster = obj.someProperty;

あなたの考えは何ですか?

4

3 に答える 3

5

最初の質問に関して:

var adjuster = db.Adjusters.FirstOrDefault(x => x.userID == user.id);
if (adjuster == null)
{
  // create adjuster record
    adjuster.id = Guid.NewGuid();
    adjuster.userID = user.id;

    db.Adjusters.InsertOnSubmit(adjuster);
}

2番目に関しては、EFはデータをロードするときにデータをキャッシュすると信じているため、最初のアクセスはuser.SomeEntity.somePropertyDBにヒットしますが、後続のすべてのアクセスはヒットしません。ただし、 Eager Loadingを調べることをお勧めします。

于 2013-05-06T19:57:41.613 に答える
2

FirstOrDefault()最初の例では、呼び出してAny()完全にミックスから除外できます。

Adjuster adj = db.Adjusters.Where(x => x.userID == user.id).FirstOrDefault();

if (adj == null)
{
  // create adjuster record
  adj.id = Guid.NewGuid();
  adj.userID = user.id;

  db.Adjusters.InsertOnSubmit(adj);
}

エンティティのナビゲーション プロパティにアクセスすると、データベースへのラウンドトリップが繰り返されるかどうかについては、答えは (ありがたいことに!) いいえです。遅延読み込みを有効にしているかどうかに応じて、そのプロパティの値は、最初に作成されたときに残りのエンティティと共に読み込まれるか、プロパティに最初にアクセスしたときに読み込まれ、後で使用するためにキャッシュされます。

だから、あなたの例...

adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;

...追加のデータベース クエリは多くても 1 つしか必要としないはずですuser

于 2013-05-06T19:58:58.887 に答える
2

最初のコードを次のように修正できます

Adjuster adj = db.Adjusters.Where(x => x.userID == user.id).FirstOrDefault();

if (adj == null)
{
    // create adjuster record
    adj = new Adjuster();
    adj.id = Guid.NewGuid();
    adj.userID = user.id;

    db.Adjusters.InsertOnSubmit(adj);
}

そして、第二部は大丈夫です。

adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;

db.SubmitChanges();

一度読み込まれると、データベースから someEntity をプルし続けるべきではありません。また、送信が呼び出されるまで何も保存されません。

于 2013-05-06T20:00:00.947 に答える