2010-04-22 13 views
8

Tôi đang sử dụng NHibernate và đang cố gắng tìm ra cách viết truy vấn, tìm kiếm tất cả tên của các thực thể của tôi, và liệt kê các kết quả. Như một ví dụ đơn giản, tôi có các đối tượng sau đây;Truy vấn NHibernate trên nhiều bảng

public class Cat { 
public string name {get; set;} 
} 

public class Dog { 
    public string name {get; set;} 
} 

public class Owner { 
    public string firstname {get; set;} 
    public string lastname {get; set;} 
} 

eventaully Tôi muốn tạo ra một truy vấn, nói ví dụ, trong đó và trả về tất cả các chủ sở hữu vật nuôi với một cái tên có chứa "ted", HOẶC vật nuôi với một tên có chứa "ted".

Dưới đây là một ví dụ của SQL Tôi muốn thực hiện:

SELECT TOP 10 d.*, c.*, o.* FROM owners AS o 
INNER JOIN dogs AS d ON o.id = d.ownerId 
INNER JOIN cats AS c ON o.id = c.ownerId 
WHERE o.lastname like '%ted%' 
OR o.firstname like '%ted%' 
OR c.name like '%ted%' 
OR d.name like '%ted%' 

Khi tôi làm điều đó bằng Tiêu chuẩn như thế này:

var criteria = session.CreateCriteria<Owner>() 
     .Add(
     Restrictions.Disjunction() 
      .Add(Restrictions.Like("FirstName", keyword, MatchMode.Anywhere)) 
      .Add(Restrictions.Like("LastName", keyword, MatchMode.Anywhere)) 
     ) 
     .CreateCriteria("Dog").Add(Restrictions.Like("Name", keyword, MatchMode.Anywhere)) 
     .CreateCriteria("Cat").Add(Restrictions.Like("Name", keyword, MatchMode.Anywhere)); 
     return criteria.List<Owner>(); 

Các truy vấn sau đây được tạo ra:

SELECT TOP 10 d.*, c.*, o.* FROM owners AS o 
    INNER JOIN dogs AS d ON o.id = d.ownerId 
    INNER JOIN cats AS c ON o.id = c.ownerId 
    WHERE o.lastname like '%ted%' 
    OR o.firstname like '%ted%' 
    AND d.name like '%ted%' 
    AND c.name like '%ted%' 

Làm cách nào tôi có thể điều chỉnh truy vấn của mình để .CreateCriteria ("Dog") và .CreateCriteria ("Cat") tạo ra OR thay vì t anh ấy VÀ?

cảm ơn sự giúp đỡ của bạn.

Trả lời

5

Hãy thử điều này, nó có thể hoạt động.

var criteria = session.CreateCriteria<Owner>() 
      .CreateAlias("Dog", "d") 
      .CreateAlias("Cat", "c") 
      .Add(
      Restrictions.Disjunction() 
       .Add(Restrictions.Like("FirstName", keyword, MatchMode.Anywhere)) 
       .Add(Restrictions.Like("LastName", keyword, MatchMode.Anywhere)) 
       .Add(Restrictions.Like("c.Name", keyword, MatchMode.Anywhere)) 
       .Add(Restrictions.Like("d.Name", keyword, MatchMode.Anywhere)) 
      ); 
+0

Cảm ơn, điều đó dường như làm điều đó. Tôi đã tìm thấy một bài đăng ở đây: http://mattthr.blogspot.com/2010/02/quey-across-join-in-nhibernate.html và sẽ cố gắng –

2

Bạn cần phải kết hợp hai tiêu chí sử dụng Expression.Or (Criteria1, criteria2)

More đây: http://devlicio.us/blogs/derik_whittaker/archive/2009/04/21/creating-a-nested-or-statement-with-nhibernate-using-the-criteria-convention.aspx

Hmm tôi nghĩ rằng nó sẽ giống như thế này (mượn một chút từ mã BuggyDigger của)

var criteria = session.CreateCriteria<Owner>() 
    .CreateAlias("Dog", "d") 
    .CreateAlias("Cat", "c") 
    .Add(Expression.Or(Expression.Like("c.Name", keyword, MatchMode.Anywhere) 
      , Expression.Like("d.Name", keyword, MatchMode.Anywhere)) 
     ); 

Nhưng tôi không nhận thấy rằng bạn muốn HOẶC mọi thứ. Trong trường hợp đó, thêm những tiêu chí này vào sự phân chia, như BuggyDigger đã cho thấy, có lẽ là con đường để đi.

+0

Cảm ơn bạn đã trả lời Alex, bạn có thể cung cấp một ví dụ hay không. Tôi đã thử những gì bạn đã làm, nhưng tôi nhận được "không thể chuyển đổi ICriteria thành Icriterion" –

+0

Làm rõ trong bài đăng của tôi, nhưng kể từ khi tôi đọc câu hỏi sai nó có thể không quan trọng;) – AlexCuse

+0

Cảm ơn sự giúp đỡ của bạn anyway! Có nó hoạt động hoàn hảo ngay bây giờ! ;) –