2011-12-27 4 views
2

У меня есть два классаNHibernate 3,2 QueryOver отличается свойством

public class News 
{ 
    public virtual int Id { get; protected set; } 
    public virtual string Topic { get; set; } 
    public virtual Category Category { get; set; } 
} 

public class Category 
{ 
    public virtual int Id { get; protected set; } 
    public virtual string Name { get; set; } 
    public virtual ISet<News> News { get; set; } 
} 

и отображение

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="News" namespace="NewsManagement.Models"> 
    <class name="News" table="News"> 
     <id name="Id"> 
      <generator class="native" /> 
     </id> 
     <property name="Date" not-null="true" /> 
     <many-to-one name="Category" fetch="join" column="CategoryId" class="Category, NHibernateManyToOne" not-null="true"/> 
    </class> 
</hibernate-mapping> 

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="News" namespace="NewsManagement.Models"> 
    <class name="Category" table="Categories"> 
     <id name="Id" column="Id"> 
      <generator class="native" /> 
     </id> 
     <set name="News" fetch="join" cascade="all-delete-orphan"> 
      <key column="CategoryId" /> 
      <one-to-many class="News, NHibernateOneToMany" /> 
     </set> 
    </class> 
</hibernate-mapping> 

И я хочу взять страничные новости, отсортированные по имени своей категории в. Вот запрос:

Session.QueryOver<News>().JoinQueryOver(x => x.Category).OrderBy(x => x.Name).Asc.Skip(pageNumber*pageSize).Take(pageSize).List<News>(); 

Но в результате я беру много дублированных новостей в моем списке. Я думаю, что это, вероятно, из-за того, что объединения включаются в сопоставлениях и используются в запросе. Итак, есть ли какое-либо решение, как сделать отдельным свойством или другим способом избежать этой проблемы?

ответ

4

Вы можете реализовать свой собственный IEqualityComparer и добавить его в свой запрос следующим образом.

class MyEqualityComparer : IEqualityComparer<News> 
{ 
    public bool Equals(News x, News y) 
    { 
     return x.Id == y.Id; 
    } 

    public int GetHashCode(News obj) 
    { 
     return obj.Id.GetHashCode(); 
    } 
} 

И затем использовать его как этот

Session.QueryOver<News>().JoinQueryOver(x => x.Category).List<News>() 
      .Distinct(new MyEqualityComparer()) 
      .OrderBy(x => x.Category.Name).Skip(pageNumber * pageSize).Take(pageSize).ToList(); 

Рассмотрим фиксируя ваши присоединиться, так что вы не получите дубликаты добавляющие .Left в свой список друзей.

Session.QueryOver<News>().Left.JoinQueryOver(x => x.Category) 

Как описано в документации.

+0

но я не могу применить 'Distinct (новый MyEqualityComparer())' 'нигде, кроме списка ()'. Если я буду применять «Distinct» к этому, это будет не то, что мне нужно, потому что оно удалит его из списка, так как я понимаю –

+0

Итак, примените его в конце после '.List ()' –

+0

он работает , но не соответствующим образом. Например, одна страница должна содержать 5 записей, но после отдельного списка она имеет только 2. Так что мне нужно как-то применить отличные не к списку –