2012-01-04 2 views
3

У меня есть класс (счет-фактура) с коллекцией (InvoiceRows).NHibernate - выбор класса по критериям по двум элементам во внутренней коллекции

Классы -

public class Invoice 
{ 
    public string ID {get; set;} 
    public List<InvoiceRow> InvoiceRows {get; set;} 
} 

public class InvoiceRow 
{ 
    public string ID { get; set;} 
    public string InvoiceID { get; set;} 
    public int RowNumber { get; set;} 
} 

Mappings -

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <class name="Domain.BusinessClasses.Invoice" table="Invoices" lazy="false"> 
    <id name="ID"> 
     <column name="ID"/> 
     <generator class="assigned"/> 
    </id> 
    <bag name="InvoiceRows" lazy="false" cascade="save-update" inverse="true" order-by="InvoiceRowNumber"> 
     <key column="InvoiceID"/> 
     <one-to-many class="Domain.BusinessClasses.InvoiceRow" /> 
    </bag> 
    </class> 

    <class name="Domain.BusinessClasses.InvoiceRow" table="InvoiceRows" lazy="false"> 
    <id name="ID"> 
     <column name="ID"/> 
     <generator class="assigned"/> 
    </id> 
    <property name="InvoiceID"> 
     <column name="InvoiceID"/> 
    </property> 
    <property name="RowNumber"> 
     <column name="RowNumber"/> 
    </property> 
    </class> 

Я хочу, чтобы все объекты, счета-фактуры, которые имеют InvoiceRow с RowNumber = 1 и RowNumber = 2. Предпочтительно с ICriterion API.

ответ

3

Мне удалось найти ответ на основании ответа Genius.

var dCriteria1 = DetachedCriteria.For<InvoiceRow>("r") 
      .SetProjection(Projections.Property("r.RowNumber")) 
      .SetProjection(Projections.Property("r.InvoiceID")) // Must be last!!!! 
      .Add(Restrictions.Eq("r.RowNumber", 1)); 

    var dCriteria2 = DetachedCriteria.For<InvoiceRow>("r") 
      .SetProjection(Projections.Property("r.RowNumber")) 
      .SetProjection(Projections.Property("r.InvoiceID")) // Must be last!!!! 
      .Add(Restrictions.Eq("r.RowNumber", 2)); 


    var invoices = Session.CreateCriteria<Invoice>() 
      .Add(Subqueries.PropertyIn("ID", dCriteria1)) 
      .Add(Subqueries.PropertyIn("ID", dCriteria2))   
      .List<Invoice>(); 
+0

Благодарим вас за окончательное разъяснение – Genius

2

должен выглядеть следующим образом (не проверено!):

var dCriteria1 = DetachedCriteria.For<InvoiceRow>("r") 
     .Add(Restrictions.EqProperty("r.InvoiceID", "i.ID")) 
     .Add(Restrictions.Eq("r.RowNumber", 1)); 
var dCriteria2 = DetachedCriteria.For<InvoiceRow>("r") 
     .Add(Restrictions.EqProperty("r.InvoiceID", "i.ID")) 
     .Add(Restrictions.Eq("r.RowNumber", 2)); 

var invoices = Session.CreateCriteria<Invoice>("i") 
    .Add(Subqueries.Exists(dCriteria1)) 
    .Add(Subqueries.Exists(dCriteria2)) 
    .List<Invoice>(); 

может быть этот код может быть оптимизирован, но идея такова.

+0

У меня возникли проблемы с реализацией этой проблемы. Не могли бы вы быть более конкретными? –

0
List<int> list=new List<int>(); 
list.Add(1); 
list.Add(2); 
DetachedCriteria forInvoice=DetachedCriteria.For<Invoice>(); 
DetachedCriteria forInvoiceRow=forInvoice.CreateCriteria("InvoiceRows"); 
forInvoiceRow.Add(Expression.In("RowNumber",list)); 
ICriteria executableCriteria = forInvoice.GetExecutableCriteria(Session); 
executableCriteria.List<Invoice>(); 

 Смежные вопросы

  • Нет связанных вопросов^_^