我编写的代码实际上可以完成它的工作,但它并不是非常理想。
在我的示例中,我有两个非常简单的表
获取人名和相关国家/地区名称(如果可用)的简单 SQL 查询如下所示
SELECT Person.Name AS Name, Country.CountryName AS Country FROM Person LEFT OUTER JOIN Country ON Country.CountryId = Person.CountryId
使用 NHibernate 获取数据的构造良好的对象看起来像这样
很简单,对。我的模型看起来像这样
namespace NHibernateLeftJoin.Models
{
public class Country
{
public virtual int CountryId { get; set; }
public virtual string CountryName { get; set; }
}
public class Person
{
public virtual int PersonId { get; set; }
public virtual string Name { get; set; }
public virtual int CountryId { get; set; }
public virtual Country CountryObject { get; set; }
}
}
和映射
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true">
<class name="NHibernateLeftJoin.Models.Country, NHibernateLeftJoin" lazy="true">
<id name="CountryId">
<generator class="native" />
</id>
<property name="CountryName" />
</class>
<class name="NHibernateLeftJoin.Models.Person, NHibernateLeftJoin" lazy="true">
<id name="PersonId">
<generator class="native" />
</id>
<property name="Name" />
<property name="CountryId" />
<many-to-one name="CountryObject" class="NHibernateLeftJoin.Models.Country" lazy="false"
column="CountryId" outer-join="true" unique="true" not-null="false" cascade="none" />
</class>
</hibernate-mapping>
这种方法的问题是 NHibernate 获取一个“Person”行并为每一行调用“Contry”表,如果我们有数千行,那不是很好。似乎不可能以与我们使用 SQL 相同的简洁方式执行此操作,或者是我使用了完全错误的方法。
任何有兴趣的人都可以在这里找到 VS 项目https://dl.dropboxusercontent.com/u/6208162/NHibernateLeftJoin.zip
谢谢
== 编辑 ==
查询可能如下所示
private static IList<Person> GetPersons()
{
using (var session = NHibernateHelper.OpenSession())
{
//using (var transaction = session.BeginTransaction()) {}
IQuery query = session.CreateQuery("FROM Person");
return query.List<Person>();
}
}
生成的sql会是这样的
NHibernate: select person0_.PersonId as PersonId1_, person0_.Name as Name1_, person0_.CountryId as CountryId1_ from Person person0_
NHibernate: SELECT country0_.CountryId as CountryId0_0_, country0_.CountryName as CountryN2_0_0_ FROM Country country0_ WHERE country0_.CountryId=@p0;@p0 = 1 [Type: Int32 (0)]
NHibernate: SELECT country0_.CountryId as CountryId0_0_, country0_.CountryName as CountryN2_0_0_ FROM Country country0_ WHERE country0_.CountryId=@p0;@p0 = 2 [Type: Int32 (0)]
NHibernate: SELECT country0_.CountryId as CountryId0_0_, country0_.CountryName as CountryN2_0_0_ FROM Country country0_ WHERE country0_.CountryId=@p0;@p0 = 3 [Type: Int32 (0)]
这对我的数据来说是非常合乎逻辑的,第一个查询它获取所有人员,然后它使用三个不同的查询获取 CountryObject 的数据(映射到用户的三个唯一国家)。
谢谢