2011-01-20 32 views
5

Tôi đang sử dụng NHibernate và có sự cố với truy vấn này ... Tôi có một Hạng mục mà tôi muốn tìm nạp bằng Id của nó. Tất cả đều tốt. Tuy nhiên, tôi cũng muốn một thuộc tính bool trên lớp Item được đặt thành true nếu một số điều kiện khác được thiết lập. Cụ thể thuộc tính này được đặt tên là IsMarked, cho biết Item được đánh dấu/stared/flagged cho người dùng đã yêu cầu nó chưa, và thông tin này được đặt trên một bảng cho biết mối quan hệ giữa Item và User.Giá trị cài đặt dựa trên bảng khác nhau trong truy vấn NHibernate

Hiện tại tôi đang tìm nạp Mục và sau đó tìm tham chiếu - cập nhật thuộc tính thành true nếu có thể tìm thấy tham chiếu. Thay vào đó, tôi có thể thực hiện điều này trong một truy vấn không?

var item = Session.Get<Item>(itemId); 

var flaggedResult = Session.CreateCriteria<ItemWithUserFlag>() 
    .Add(Restrictions.Eq("User.Id", userId)) 
    .Add(Restrictions.Eq("Item", item)) 
    .List<ItemWithUserFlag>(); 

if (flaggedResult.Count > 0) 
    item.IsMarked = true; 

return item; 
+0

như thế nào lớp học của bạn ánh xạ? Có sự liên quan nhiều đến nhiều giữa Người dùng và Hạng mục không? –

+0

Tôi đang sử dụng Fluent cho ánh xạ. Có một mối quan hệ nhiều-nhiều được thể hiện trong một lớp riêng biệt ItemWithUserFlag. Người dùng không có mối quan hệ trực tiếp với Item và Item không có mối quan hệ trực tiếp với User. ItemWithUserFlag có một tham chiếu được thiết lập cho người dùng và mục. – stiank81

Trả lời

7

Làm thế nào về việc sử dụng formula cùng với filter trong lập bản đồ tài sản của bạn:

<property name="IsMarked" formula="(select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = ItemId and ItemWithUserFlag.UserId = :UserFilter.userId)" /> 

Và lọc def:

<filter-def name="UserFilter"> 
    <filter-param name="userId" type="Int32"/> 
</filter-def> 

Điều đó sẽ dẫn đến một cái gì đó giống như

SELECT Item.*, (select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = Item.ItemId and ItemWithUserFlag.UserId = ?) AS IsMarked FROM Item 

Miễn là IsMarked được định nghĩa là bool, nếu count(*) trả về 0, số này sẽ được chuyển đổi thành false và nếu bất kỳ điều gì > 0, số này sẽ được chuyển đổi thành true.

EDIT: đại diện thạo

public class ItemMap : ClassMap<Item> 
{ 
    public ItemMap() 
    { 
     /// ... whatever 
     Map(x => x.IsMarked).Formula("(select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = ItemId and ItemWithUserFlag.UserId = :UserFilter.userId)"); 
    } 
} 

public class UserFilter : FilterDefinition 
{ 
    public UserFilter() 
    { 
     WithName("UserFilter") 
      .AddParameter("userId", NHibernate.NHibernateUtil.Int32); 
    } 
} 
+0

Thx! Chưa thử nghiệm, nhưng âm thanh như thế này sẽ hoạt động. Vấn đề trong trường hợp của tôi là tôi sử dụng FluentNhibernate cho các ánh xạ. Dunno nếu tôi có thể xác định một số ánh xạ i xml cùng một lúc, hoặc nếu cùng có thể được diễn tả trong Thông thạo. Vì vậy, không có cách nào để đạt được điều này trực tiếp trong truy vấn? – stiank81

+0

@ stiank81 Tôi đã thêm những gì tôi tin rằng nên làm việc với Fluent. –

+0

@ stiank81 Về việc đạt được điều này trong truy vấn: Tôi tin rằng không có cách nào. Về mặt logic, những gì bạn muốn không phải là một hạn chế hoặc những gì, nhưng một cột được tính toán, vì vậy tôi nghĩ rằng nó phải được thực hiện thông qua ánh xạ. Nhưng, tôi không phải là một chuyên gia về nHibernate và do đó tôi không thể nói cho bạn chắc chắn. –

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