2011-09-06 90 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 –