NHibernate - получить класс по критериям более двух элементов во внутренней коллекции - PullRequest
3 голосов
/ 04 января 2012

У меня есть класс (Invoice) с коллекцией (InvoiceRows).

Классы -

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;}
}

Отображения -

<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>

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

Ответы [ 3 ]

3 голосов
/ 08 января 2012

Мне удалось найти ответ на основе 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>();
2 голосов
/ 04 января 2012

должно выглядеть так (не проверено!):

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 голосов
/ 04 января 2012
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>();
...