2011-11-14 12 views
5

Kolejny problem z JOIN NHibernate.NHibernate - wiele JOIN do tego samego stołu przy użyciu różnych kluczy

Próbuję połączyć dwie różne właściwości z jednej tabeli za pomocą dwóch różnych kluczy . Ale nie mogę uzyskać drugiej właściwości JOIN.

uproszczony przykład -

Moja klasa -

namespace Domain 
{ 
    public class Message 
    { 
     #region private Members 

     private string _id; 
     private string _senderID; 
     private string _recipientID; 
     private string _recipientName; 
     private string _senderName; 

     #endregion 

     #region Public Properties 

     public virtual string ID 
     { 
      get { return _id; } 
      set { _id = value; } 
     } 

     public virtual string ID 
     { 
      get { return _id; } 
      set { _id = value; } 
     } 

     public virtual string SenderID 
     { 
      get { return _senderID; } 
      set { _senderID= value; } 
     } 

     public virtual string RecipientID 
     { 
      get { return _recipientID; } 
      set { _recipientID= value; } 
     } 

     public virtual string SenderName 
     { 
      get { return _senderName; } 
      set { _senderName= value; } 
     } 

     public virtual string RecipientName 
     { 
      get { return _recipientName; } 
      set { _recipientName= value; } 
     } 

     #endregion 

     #region Constructors 

     public Message() 
     { 
      _id = Guid.NewGuid().ToString(); 
     } 

     #endregion 
    } 
} 

Mapowanie -

<class name="Domain.Message" table="Messages" > 
    <id name="ID"> 
     <column name="OID"/> 
     <generator class="assigned"/> 
    </id> 
    <property name="SenderID" unique="true"> 
     <column name="SenderID" unique="true"/> 
    </property> 
    <property name="RecipientID" unique="true"> 
     <column name="RecipientID" unique="true"/> 
    </property> 
    <join table="CompanyData" optional="true" > 
     <key column="CompanyID" property-ref="SenderID" /> 
     <property name="SenderName" column="CompanyName" unique="true" lazy="false"/> 
    </join> 
    <join table="CompanyData" optional="true" > 
     <key column="CompanyID" property-ref="RecipientID" /> 
     <property name="RecipientName" column="CompanyName" unique="true" lazy="false"/> 
    </join> 
</class> 

ale otrzymuję następujący SQL -

SELECT this_.OID as OID30_0_, this_.SenderID as Sender30_0_, 
this_.RecipientID as Recipient30_0_, this_1_.CompanyName as SiteID9_0_ 
FROM Messages this_ 
left outer join CompanyData this_1_ on 
this_.SenderID=this_1_.CompanyID 
left outer join CompanyData this_2_ on 
this_.RecipientID=this_2_.CompanyID 

I chcę -

SELECT this_.OID as OID30_0_, this_.SenderID as Sender30_0_, 
this_.RecipientID as Recipient30_0_, this_1_.CompenyName as 
SiteID9_0_ , this_2_.CompanyName as SiteID10_0_ 
FROM Messages this_ 
left outer join CompanyData this_1_ on 
this_.SenderID=this_1_.CompanyID 
left outer join CompanyData this_2_ on 
this_.RecipientID=this_2_.CompanyID 

Używam NHibernate 3.2

Thanks

+0

nie widzę niczego złego w mapowaniu. Czy możesz również opublikować kod zajęć? –

+0

Co to jest nazwa odbiorcy po uruchomieniu? Wartość SenderName? Jestem skłonny pomyśleć, że to może być błąd. nHibernate może starać się optymalizować niepoprawnie dla ciebie. –

+0

Tak, masz rację, nazwa odbiorcy jest wypełniona wartością SenderName. Czy jest coś, co mogę zrobić, aby wyłączyć optymalizację? –

Odpowiedz

2

Najwyraźniej nie można tego zrobić w tej chwili z odwzorowań NHibenate. Najbliższym rozwiązaniem, zaproponowanym przez Spencer Ruport, jest utworzenie widoku i mapowanie obiektu do niego.

3

Przez cały dzień czaiłem się w Internecie, aby znaleźć rozwiązanie tego samego problemu. Co znalazłem to wątek na hibernate board. Wziąłem rozwiązanie z Ashkan Aryan. Więc jeśli ktoś inny ma bóle głowy dotyczące rozwiązania i nie chce korzystać z widoków, opublikuję mój kod, którego teraz używam.

Muszę użyć od 1 do 12 połączeń na tym samym stole, więc tworzenie widoków jest bardzo mylące.

private void addParagraphsQuery(DetachedCriteria sourceQuery, List<ParagraphContentArgument> paragraphsArguments) 
{ 
    DetachedCriteria dc; 
    Conjunction conjunction = Restrictions.Conjunction(); 
    string alias = string.Empty; 

    if (paragraphsArguments != null && paragraphsArguments.Count > 0) 
    { 
     for (int i = 0; i < paragraphsArguments.Count; i++) 
     { 
      alias = "p" + i.ToString(); 
      dc = DetachedCriteria.For<Document>().SetProjection(Projections.Id()); 
      dc.CreateAlias("paragraphList", alias); 
      dc.Add(Restrictions.Eq(alias + ".paragraphSectionTemplate", paragraphsArguments[i].ParagraphTemplate)); 
      dc.Add(Restrictions.Like(alias + ".content", paragraphsArguments[i].Argument, MatchMode.Anywhere)); 
      conjunction.Add(Property.ForName("id").In(dc)); 
     } 
    } 
    sourceQuery.Add(conjunction); 
} 

Pozdrawiam,

Mariusz

Powiązane problemy