2009-06-02 18 views
24

Tôi muốn tải các thực thể gốc và mong muốn tải tất cả các bộ sưu tập con của nó và các thành viên tổng hợp.Mong muốn tải bộ sưu tập con bằng NHibernate

Đã cố gắng sử dụng SetFetchMode trong FluentNHibernate, nhưng tôi nhận được bản sao trong một trong các bộ sưu tập con vì tôi có độ sâu 3 cấp. DistinctRootEntityResultTransformer tiếc là chỉ loại bỏ các bản sao gốc.

return Session.CreateInvoiceBaseCriteria(query, archived) 
    .AddOrder(new Order(query.Order, query.OrderType == OrderType.ASC)) 
    .SetFetchMode("States", FetchMode.Eager) 
    .SetFetchMode("Attestations", FetchMode.Eager) 
    .SetFetchMode("AttestationRequests", FetchMode.Eager) 
    .SetFetchMode("AttestationRequests.Reminders", FetchMode.Eager) 
    .SetResultTransformer(new DistinctRootEntityResultTransformer()) 
    .List<Invoice>(); 

Tôi có thể sử dụng nhiều truy vấn hoặc điều gì đó tương tự để lưu trữ này không?

Hơn nữa, cách tiếp cận này sẽ không dẫn đến các tập kết quả rất lớn không cần thiết từ cơ sở dữ liệu không?

Mọi đề xuất?

Trả lời

0

Trong khi nó có thể không được chính xác những gì bạn đang tìm kiếm, tôi sẽ khuyên bạn nên nhìn vào bài viết này:

Eager loading aggregate with many child collections

Nếu bạn nhìn xung quanh phần còn lại của trang web mà bạn sẽ tìm thấy nhiều hơn các bài viết mà thảo luận háo hức tải và các công cụ tuyệt vời khác.

+2

Thực sự là một bài viết hay, nhưng không chắc chắn liệu tôi có thể áp dụng nó cho tình huống của mình hay không. Các giải pháp được mô tả trong bài viết về mong muốn tải một thực thể gốc cụ thể, vấn đề của tôi là tôi muốn mong muốn tải một bộ sưu tập của các thực thể gốc. Nếu tôi sử dụng MultiCritera, tôi cần tìm cách kết nối tất cả các truy vấn khác nhau mà không cần chỉ định một thực thể cụ thể. Gợi ý làm thế nào có thể được thực hiện? – Kristoffer

+0

Ví dụ đó chỉ có một cấp phân cấp bổ sung, nhưng không có cháu, mà MultiQuery/MultiCriteria có vẻ khá vô dụng, vì các truy vấn sau không thể tham chiếu kết quả từ các truy vấn trước đó (như truy vấn số 1: chọn rootObjects r left join fetch children c nơi ...; Truy vấn # 2: chọn cháu g nơi cha mẹ trong c). –

8

Tìm ra giải pháp nhưng không đẹp. Đầu tiên tôi đi và tìm tất cả các ID hóa đơn, sau đó tôi sử dụng chúng trong multiquery và sau đó ở cuối lọc kết quả thông qua một HashedSet. Bởi vì số lượng lớn các mặt hàng đôi khi tôi không thể sử dụng Restriction.In bình thường.In và đã buộc phải gửi nó như là một chuỗi.

Mọi chỉnh sửa được đề xuất?

var criteria = Session.CreateInvoiceBaseCriteria(query, archived) 
    .SetProjection(Projections.Id()); 

var invoiceIds = criteria.List<int>(); 
if (invoiceIds.Count > 0) 
{ 
    var joinedIds = JoinIDs(criteria.List<int>()); // To many ids to send them as parameters. 

    var sql1 = string.Format("from Invoice i inner join fetch i.States where i.InvoiceID in ({0}) order by i.{1} {2}", joinedIds, query.Order, query.OrderType.ToString()); 
    var sql2 = string.Format("from Invoice i inner join fetch i.AttestationRequests where i.InvoiceID in ({0})", joinedIds); 
    var sql3 = string.Format("from Invoice i inner join fetch i.Attestations where i.InvoiceID in ({0})", joinedIds); 

    var invoiceQuery = Session.CreateMultiQuery() 
     .Add(sql1) 
     .Add(sql2) 
     .Add(sql3); 

    var result = invoiceQuery.List()[0]; 

    return new UniqueFilter<Invoice>((ICollection)result); 
} 

return new List<Invoice>(); 
+0

Điều đó là kỳ quặc, Các truy vấn được tìm nạp dưới dạng các truy vấn đơn lẻ. – Kristoffer

+0

+1, Thực sự là (và không may) cách tốt nhất (hiệu suất khôn ngoan) để đạt được điều này. –

+0

Tôi đang ở trong tình trạng tương tự (cố gắng kéo 3 cấp cùng một lúc). Mặc dù giải pháp của bạn loại bỏ các bản sao, nó chỉ có vẻ là 2 cấp độ sâu. Câu hỏi ban đầu của bạn bao gồm cấp độ 3 được gọi là "AttestationRequests.Reminders" không được bao gồm trong câu trả lời của bạn. – MylesRip

2

Để trả lời câu hỏi của bạn: có, kết quả là kết quả rất lớn.

Tôi đề nghị để:

  • chỉ ngây thơ viết các truy vấn của bạn mà không háo hức lấy
  • On nơi nhất định, chấm háo hức lấy, nhưng chỉ có một cho mỗi truy vấn
  • nếu bạn thực sự có được vấn đề hiệu suất mà bạn không thể giải quyết bằng chỉ mục hoặc bằng cách tăng cường các truy vấn và chiến lược lập bản đồ, sử dụng giải pháp của bạn với nhiều truy vấn.