2013-10-09 24 views
5

Tôi đang cố gắng để lựa chọn một tổ chức và lấy một danh sách có liên quan:NHibernate QueryOver với Fetch kết quả truy vấn nhiều sql và db chạm

Session.QueryOver<UserRole>() 
      .Fetch(x => x.UsersInRole).Eager 
      .List(); 

nào dẫn đến rất nhiều hits cơ sở dữ liệu. Người đầu tiên là một cái gì đó như:

SELECT ... FROM UserRoles 
left outer join UsersInRoles on ... 

Và hàng trăm các truy vấn riêng biệt hơn mà trông giống như sau:

SELECT ... FROM UsersInRoles 
left outer join UserRoles on ... 
WHERE UserRoles.UserId=? 

Việc lập bản đồ là như sau:

public class UserRoleMap : ClassMap<UserRole> 
{ 
    public UserRoleMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.RoleName); 
     HasManyToMany(x => x.UsersInRole) 
     .Inverse() 
     .LazyLoad() 
     .Table("UsersInRoles"); 
    } 
} 

Trả lời

3

Tôi sẽ nói, rằng hành vi này là những gì chúng ta nên mong đợi. Chúng ta hãy có một kịch bản, trong đó chúng ta có trong hệ thống 2 thành viên và 2 vai trò

User1 - Role1 // has only Role1 
User2 - Role1 // now we see that Role2 has more then User1 
User2 - Role2 

Hãy nói rằng, đó là truy vấn đầu tiên, sẽ lấy chỉ User1 và nó nhiều-nhiều mối quan hệ Role1. Những gì chúng ta có trong ISession vào lúc này chỉ User1 là, vì vậy các thiết lập của người dùng cho Role1không đầy đủ(chúng ta không thể tái sử dụng đối tượng được nạp vào ISession vào lúc này). Nhưng làm thế nào chúng ta nên biết chúng ta đang ở đâu? Tất cả dữ liệu được tải cho Role1 là hoặc không có trong phiên không?

Truy vấn mới, tải dữ liệu cho Role1 phải được cấp. Và bằng cách này, chúng ta có thể ở cuối có dosens của các truy vấn này ...

Những gì tôi xem như là giải pháp tốt nhất (tôi đang sử dụng nó trong hầu hết các tình huống) là cài đặt batch-size: 19.1.5. Using batch fetching

HasManyToMany(x => x.UsersInRole) 
    ... 
    .BatchSize(25) 

Đánh dấu tất cả bản đồ bộ sưu tập của bạn với .BatchSize(25) và thực hiện điều đó ngay cả đối với bản đồ Lớp. Điều đó sẽ gây ra nhiều hơn sau đó 1 SQL Script, nhưng ở cuối không nhiều hơn thì 1 + (2-4) phụ thuộc vào kích thước lô và kích thước trang.

+0

Đã cố gắng đề xuất của bạn. Kết quả trong 1 + 12 truy vấn - MUCH tốt hơn trước đó, nhưng không phải là có một cách để làm cho nó ít hơn 12? (tăng kích thước lô?) - chi phí của kích thước lô là bao nhiêu? Tôi sẽ nói rằng nếu nó là tất cả tốt nó sẽ được thiết lập theo mặc định. Kích thước lô có phải là giải pháp duy nhất không? Không phải là có thể tham gia mà sẽ dẫn đến 2 truy vấn? Nếu tôi cần thiết để viết nó tự của tôi với SQL đơn giản, tôi nghĩ rằng 2 truy vấn sẽ là đủ. Cảm ơn. –

+1

Nếu có giải pháp nào tốt hơn kích thước hàng loạt, có thể, tôi không chắc chắn. Lý do tại sao điều này không được bật theo mặc định, có thể là một thực tế, rằng đây là vi phạm logic đơn giản: Proxy của đối tượng uninitialize là một trình điều khiển. Nó trực tiếp đi cho dữ liệu của nó khi cần thiết. Việc định cỡ hàng loạt di chuyển một số nỗ lực nhiều hơn vào phiên để tham gia các CHỌN này. Dù sao, kích thước lô là trên tất cả * bộ sưu tập của chúng tôi * và ánh xạ lớp. Và hiệu suất là tuyệt vời ngay cả trên bộ lớn –

Các vấn đề liên quan