User
RavenDB にオブジェクトを格納します。それぞれUser
にUser.Id
プロパティがあります。
次のように、メンター/メンティー関係を作成するために 2 つのをリンクするRelationship
クラスもあります。User.Id
public class User
{
public string Id { get; set; }
public string UserName { get; set; }
... more properties
}
public class Relationship
{
public string Id { get; set; }
public string MentorId { get; set; }
public string MenteeId { get; set; }
public RelationshipStatus Status { get; set; }
}
ここで、特定のメンターのメンティーのリストを取得したいと考えています。私は次の方法でこれを行いました:
public static List<User> GetMentees(IDocumentSession db, string mentorId)
{
var mentees = new List<User>();
db.Query<Relationship>()
.Where(r => r.MentorId == mentorId)
.Select(r => r.MenteeId)
.ForEach(id => mentees.Add(db.Load<User>(id)));
return mentees;
}
IDocumentSession
これは問題なく動作しているように見えますが、私の肩に乗っているコーディング エンジェルは、 (db)のネストされた使用と、リストLoad
を埋めるために複数の呼び出しが必要であることから発せられる臭いに鼻をすくめています。Mentees
ベスト プラクティスの RavenDB 構文を使用してこの方法を最適化するにはどうすればよいですか?
編集 データベースへの複数の呼び出しの問題を解決してくれた @Jonah Himango (以下の受け入れられた回答を参照) に感謝します。さらに、「Memoize」という新しい拡張メソッドを作成して、外部の「メンティー」結果リストを不要にしました (上記のコードを参照)。
これが最適化されたコードです。お気軽にコメントして、さらに絞り込んでください。
リンク
public static List<User> GetMentees(IDocumentSession db, string mentorId)
{
return db.Query<Relationship>()
.Customize(x => x.Include<Relationship>(o => o.MenteeId))
.Where(r => r.MentorId == mentorId)
.Memoize()
.Select(r => db.Load<User>(r.MenteeId))
.ToList();
}
拡張方法
public static List<T> Memoize<T>(this IQueryable<T> target)
{
return target.ToList();
}
注ToList()
: この拡張メソッドは完全に不必要に見えるかもしれません (実際にはそうです) が、リストを作成するためではなく、Linq ステートメントの実行を強制するために、という関数を呼び出さなければならないという私のオタク腺を苛立たせます。したがって、私の拡張メソッドの名前ToList()
は、はるかに正確なMemoize()
.