2011-09-06 176 views
1

幫我翻譯成正確的NHibernate這個...如何用NHibernate查詢Oracle數據庫?

我有2個表Oracle數據庫:

Employees: 
    Id (unique id) 
    FirstName (string) 
    LastName (string) 
    Location (string) 

Locations: 
    Name (string) 
    Address (string) 

正如你可以看到員工表中有一個唯一的ID,但位置表沒有無論如何。名稱字段是一個常規字段,不是唯一的。

在Oracle SQL,我可以運行以下查詢:

SELECT * 
FROM Employees e 
LEFT OUTER JOIN Locations l 
ON e.Location = l.Name 
WHERE e.Id = 42 

其中僱員42的位置,具有在位置表2點的行,所以該查詢返回2行,一個用於發現對於每個位置員工42.

那麼,我想不出如何將其轉換成NHibernate映射+查詢(我使用流利NHibernate)。我傾向於認爲我應該將Employees.Location映射爲Locations.Name的引用,所以當運行我的HQL查詢時,它應該返回2個對象,但NHibernate不會讓我從Reference中檢索列表。所以我嘗試了HasMany,但它也不起作用,因爲NHibernate希望位置中的字段指向員工,這很有意義。

我的HQL查詢看起來是這樣的:

select e 
from Employees e 
left join e.Locations l 
where e.SGId like :sgId 

爲什麼我在常規的SQL,而不是在NHibernate的做到這一點?

謝謝。

回答

1

我找到了解決方案,你必須將HasMany(x => x.Locations)與.PropertyRef(「Location」)結合使用,以便hibernate知道Employee中用於連接的字段應該是Location(而不是id)的員工是默認的)。

class Employee 
{ 
    public virtual int Id {get;set} 
    public virtual string FirstName {get;set;} 
    public virtual string LastName {get;set;} 
    public virtual string Location {get;set;} 
    public virtual IList<Location> Locations {get;set;} 
} 

class EmployeeMapping : ClassMap<Employee> 
{ 
    public EmployeeMapping() 
    { 
     Id(x=>x.Id); 
     Map(x=>x.FirstName); 
     Map(x=>x.LastName); 
     Map(x=>x.Location); 
     HasMany<Location>(x => x.Locations) 
      .PropertyRef("Location") 
      .KeyColumn("Name"); 
    } 
} 

此外,我發現我的方法中的一些缺陷,主要是由於我正在使用的古怪的遺留數據庫。這並不會改變解決方案,但我想補充一點,如果您正在處理的其中一個表格沒有唯一的ID,那麼您遇到了麻煩。 Hibernate需要一個唯一的ID,所以在我的情況下,我必須想出一個由多個字段組成的複合ID,以使其獨一無二。這是另一場辯論,但我想在此提及它以幫助未來研究此主題的任何人。

0

對於你映射你需要使用一個集合/數組/列表/集對象和你的員工的hasMany映射的位置,如果它要返回2個位置的一個員工

class Employee 
{ 
    public virtual int Id {get;set} 
    public virtual string FirstName {get;set;} 
    public virtual string LastName {get;set;} 
    public virtual IList<Location> Location {get;set;} 
} 

class EmployeeMapping : ClassMap<Employee> 
{ 
    public EmployeeMapping() 
    { 
     Id(x=>x.Id); 
     Map(x=>x.FirstName); 
     Map(x=>x.LastName); 
     HasMany<Location>(x => x.Location) 
        .KeyColumn("Name") 
        .PropertyRef("Location") 
        .LazyLoad(); 

    } 
} 
+0

這不會工作,因爲你缺少.PropertyRef(),事實證明。我用這個新元素添加了一個新的解決方案。謝謝您的幫助。 – md1337

+0

是的,你的權利。 :)更新後,供將來參考。 +1 –