2009-08-26 20 views
12

Điều này có thể là điều gì đó hiển nhiên nhưng tôi đã đập đầu vào nó trong vài giờ và không thể tìm ra nơi tôi đang đi sai.Ngắt kết nối NHibernate dẫn đến truy vấn VÀ thay vì HOẶC

Tôi đang cố gắng chạy một đoạn mã nhỏ để kiểm tra việc thêm OR tiêu chí vào truy vấn NHibernate. Đây là mã tôi có:

using (ISession session = NHibernateHelper.OpenSession()) 
{ 
    ICriteria criteria = session.CreateCriteria<TestObject>(); 

    int[] ids = {1, 2, 3}; 
    foreach (int id in ids) 
    { 
     ICriterion criterion = Restrictions.Eq("Id", id); 
     criteria.Add(Restrictions.Disjunction().Add(criterion)); 
    } 

    IList<TestObject> items = criteria.List<TestObject>(); 
    return items; 
} 

Nó chỉ đơn giản là tôi mong muốn trả về tất cả các đối tượng thử nghiệm với ID 1-3. Nhưng, khi tôi chạy mã, truy vấn được tạo ra là tìm một đối tượng có ID = 1 AND ID = 2 AND ID = 3. Điều đó, không ngạc nhiên, không trả về bất kỳ thứ gì.

Bản đồ được thiết lập chính xác (tôi có thể thêm/chỉnh sửa/xóa/liệt kê tất cả các đối tượng) và có các đối tượng trong đó với các ID này.

Tôi đang làm điều gì đó rõ ràng là sai? Bất kỳ mẫu sử dụng Disjunction tôi đã nhìn thấy trực tuyến tất cả dường như sử dụng nó theo cách này. Tôi chỉ không hiểu tại sao nó tiếp tục sử dụng AND.

Cảm ơn.

Trả lời

16

Sự cố của bạn nằm trong thực tế là bạn đang tạo một sự cố mới gián đoạn mỗi lần (trong vòng lặp). Những gì bạn cần làm là:

int[] ids = {1, 2, 3}; 
ICriterion disjunction = Restrictions.Disjunction(); 
foreach (int id in ids) 
{ 
    ICriterion criterion = Restrictions.Eq("Id", id) 
    disjunction.Add(criterion); 
} 
criteria.Add(disjunction); 

Cú pháp có thể là một sai chút - Tôi là một chàng trai Hibernate thay vì .NET :-)

Để làm rõ, mã ban đầu của bạn sẽ tạo ra một cái gì đó tương tự (in pseudo-code):

WHERE (OR(ID=1)) AND (OR(ID=2)) AND (OR(ID=3)) 

Vì không có gì để "HOẶC" đến, các liên kết bị bỏ qua âm thầm.

+1

Magic, mà làm việc một điều trị. Làm cho tinh thần khi tôi nhìn vào mã của bạn - Tôi không bao giờ nghĩ rằng nó sẽ là "và" ing "cùng nhau OR cá nhân. Thay đổi nhỏ duy nhất đối với mã của bạn là tạo ra sự tách rời là: Ngắt kết nối = Hạn chế.Disjunction(); (ICriterion không có 'add'). Cảm ơn! –

5

đang cập nhật dựa trên câu trả lời của ChssPly76:

using (ISession session = NHibernateHelper.OpenSession()) 
{ 
    ICriteria criteria = session.CreateCriteria<TestObject>(); 
    Junction disjunction = Restrictions.Disjunction(); 

    int[] ids = {1, 2, 3}; 
    foreach (int id in ids) 
    { 
     ICriterion criterion = Restrictions.Eq("Id", id); 
     disjunction.Add(criterion); 
    } 
    criteria.Add(disjunction); 


    IList<TestObject> items = criteria.List<TestObject>(); 
    return items; 
} 
Các vấn đề liên quan