2012-09-07 39 views
1

我將User對象存儲在RavenDB中。每個User都有一個User.Id屬性。使用RavenDB,我如何有效地檢索「外鍵」相關項目列表

我也有一個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」的新擴展方法,以消除對外部「被指導人」結果列表的需求(請參閱上面的代碼)。

這是優化的代碼。請隨時評論和進一步細化。

LINQ的

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()的函數,不要創建列表,而是強制執行L inq語句。所以我的擴展方法只是將ToList()重新命名爲更準確的Memoize()

回答

1

你想使用.Include query customization告訴烏鴉,包括相關的用戶對象斷開每個關係:

db.Query<Relationship>() 
      .Customize(x => x.Include<Relationship>(o => o.MenteeId)) 
      .Where(r => r.MentorId == mentorId) 
      .Select(r => r.MenteeId) 
      .ForEach(id => mentees.Add(db.Load<User>(id))); // .Load no longer makes a call to the DB; it's already loaded into the session! 

Relevant documentation here

調用加載()得到徹底解決客戶端(即沒有0​​額外的請求到RavenDB服務器),因爲[related] 對象已經通過.Include調用獲取。

相關問題