2011-09-09 33 views
5

Tôi đang sử dụng truy vấn này:ngăn chặn chéo không cần thiết tham gia vào truy vấn đếm tạo ra mã sql

return from oi in NHibernateSession.Current.Query<BlaInteraction>() 
select new BlaViewModel 
{ 
    ... 

    NoPublications = oi.Publications.Count(), 

    ... 
}; 

BlaInteraction chứa một IList các ấn phẩm (ví dụ: thực thể). Để xác định số lượng ấn phẩm, một trong số đó không thực sự cần phải thực hiện tất cả các phép nối cho một ấn phẩm. Tôi có thể ngăn chặn nhibernate bằng cách sử dụng tham gia trong sql được tạo ra (ví dụ: using projection ???) bằng cách nào đó?

Cảm ơn.

Christian

PS:

Đây là những gì NH sản xuất (hơi thích nghi):

select cast(count(*) as INT) from RelationshipStatementPublications publicatio21_, Publication publicatio22_ inner join Statements publicatio22_1_ on publicatio22_.StatementId=publicatio22_1_.DBId where publicatio21_.StatementId = 22762181 and publicatio21_.PublicationId=publicatio22_.StatementId 

Đây là những gì sẽ là đủ:

select cast(count(*) as INT) from RelationshipStatementPublications publicatio21_ where publicatio21_.StatementId = 22762181 
+0

Bạn có biết rằng nó * đang * hydrating ấn phẩm? SQL Profiler nói gì đang thực sự được chạy trên máy chủ? – AakashM

+0

Cảm ơn - xin lỗi bạn đã đúng. Các tham gia không có gì để làm với 'hydrat hóa'. Tôi đã chỉnh sửa câu hỏi và thêm một số sql. – cs0815

+0

(không phải là một chuyên gia nhibernate) thực tế là nó tạo ra một implciti 'CROSS JOIN' (các bảng trong mệnh đề' FROM' không được tham gia rõ ràng) cho thấy NHibernate thiếu một số kiến ​​thức về mối quan hệ giữa các đối tượng; tuy nhiên, trước hết tôi sẽ muốn kiểm tra các kế hoạch thực thi SQL của truy vấn của nó và truy vấn lý tưởng - có thể là * SQL Server * có thể làm việc dễ dàng. – AakashM

Trả lời

2

Ok là giải pháp tốt nhất mà tôi đã tìm thấy cho đến nay là sử dụng một công thức FNH:

mapping.Map(x => x.NOPublications).Formula("(select count(distinct RelationshipStatementPublications.PublicationId) from RelationshipStatementPublications where RelationshipStatementPublications.StatementId = DBId)"); 

public virtual int NOPublications {get; private set;} 

khi tôi lập bản đồ từ tên miền để mô hình xem tôi sử dụng:

NoPublications = oi.NOPublications, 

Christian

3

Tại sao không thể bạn chỉ cần tạo một truy vấn khác?

Session.QueryOver<Publication>().Where(x => x.BlaInteractionId == idSentAsParameter).Select(Projections.RowCount()).SingleOrDefault<int>(); 

Tôi nghĩ rằng đó là sẽ làm việc

return from oi in NHibernateSession.Current.Query<BlaInteraction>() 
select new BlaViewModel 
{ 
    ... 
    NoPublications = Session.QueryOver<Publication>().Where(x => x.BlaInteractionId == oi.Id).Select(Projections.RowCount()).SingleOrDefault<int>(); 

    ... 
}; 

chỉnh sửa khác, bạn đã thử lazy="extra"?

+0

Cảm ơn. Bạn có thể giải thích điều này không? Tôi có một lớp BlaInteraction chứa một IList . Truy vấn của tôi ánh xạ các thuộc tính nhất định của BlaInteraction cho mô hình khung nhìn và đếm số lượng ấn phẩm của mỗi BlaInteraction (TOP n). Lý do cho thẩm định của tôi là tôi muốn sử dụng đầy đủ 'công cụ biểu thức dựa trên LINQ' của telerik, tạo ra tất cả 'công cụ' để lọc, phân trang và phân loại. – cs0815

+0

Thêm một ví dụ khác, kiểm tra xem ok của nó –

+0

Điều này không hoạt động và tôi đã thử điều này trước khi bạn đăng nó. Những thứ là BlaInteraction có nguồn gốc từ tuyên bố. bất kỳ câu lệnh nào có Ilist được ánh xạ bằng ánh xạ.HasManyToMany (x => x.Publications) .Table ("RelationshipStatementPublications"); và tôi cũng có một thực thể RelationshipStatementPublications chuyên dụng. vì vậy một cái gì đó như thế này sẽ làm việc: NoPublications = NHibernateSession.Current.QueryOver (). Where (x => x.Statement.Id == oi.Id) .Select (Projections.RowCount()). SingleOrDefault () , nhưng tôi nhận được một ngoại lệ đường dẫn. – cs0815

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