2010-09-20 65 views
2

我有2个实体角色&翻译。
角色 - > ROLE_ID,代码
翻译 - >代码,语言名称NHibernate左外部加入不相关的实体

的想法是说对了一定的作用,它有英文名,法文名等。翻译('Rol_001','英语','')&翻译('Rol_001','法语','')。

我想表达的HQL下面的SQL查询:


select r.Role_ID, t.Name 
from Role r left outer join Translation t 
    on r.Code = t.Code and t.Language = @lang; 

在我的映射文件我没有2个实体,但下面的HQL查询工作之间的关系,就好像它是内部联接


IQuery query = session.CreateQuery("select new Lookup(r.Role, t.Name) from Role r, Translation t where r.Code = r.Code and t.Language = :language"); 

如果我将HQL更改为左外连接,我得到了预期的加入异常的路径。

你能帮我一下吗:
1-我需要改变我的映射文件吗?
2-如果我可以保持映射文件原样,如何在HQL中写入这样的查询?
3- HQL如何真正起作用?为什么这样一个简单的外连接查询不起作用?我必须在这里错过一些东西!

编辑:
现在我使用基于suggetion下面的代码使用CreateSQL:


ISQLQuery query = session.CreateSQLQuery("select m.MedicineTypeID, t.Name, m.IsDeleted from MedicineType m left outer join Translation t on m.Code = t.Code and t.Language = :language"); 
query.SetString("language", language); 
IList rawLookup = query.List(); 

IList medicineTypesLookup = new List(rawLookup.Count); 
foreach (object[] lookup in rawLookup) 
{ 
    medicineTypesLookup.Add(new Lookup((int)lookup[0], (string)lookup[1], (bool)lookup[2])); 
} 
return medicineTypesLookup; 

但是,这是工作,我想用query.List()直接得到结果而不是自己转换它。
我试图使用query.AddEntity(typeof(Lookup));但我得到例外NHibernate.MappingException: No persister for: DAL.Domain.Lookup
Lookup只是一个POCO,并没有映射到任何数据库表。它的映射文件仅仅是<import class="Lookup" />

+2

HQL的正确方法使用映射关系,而不是任意的连接子句。你可以使用SQL来实现。 – 2010-09-21 19:43:30

+0

这是一个SQL Server CE,我可以直接使用NHibernate执行SQL语句,还是应该使用SqlCeConnection和SqlCeCommand来执行ExecuteReader的sql语句并获得结果? – 2010-09-22 14:58:00

+0

我看到我可以使用session.CreateSQLQuery,但结果是Object []。我试图找到一种方法来得到IList 的结果。 – 2010-09-22 23:44:17

回答

2

我终于找到了答案:

ISession session = NHibernateHelper.Session; 
ISQLQuery query = session.CreateSQLQuery("select m.MedicineTypeID as ID, t.Name, m.IsDeleted from MedicineType m left outer join Translation t on m.Code = t.Code and t.Language = :language"); 
query.setString("language", language); 
IList lookup = query.SetResultTransformer(Transformers.AliasToBean()).List(); 
return lookup; 
而查找是一个POCO类带有参数的构造函数和3个属性ID ,Name和IsDeleted。

我想感谢Kelly和Diego Mijelshon的提示。虽然他们没有提供完整的答案,但使用Session.CreateSqlQuery()是一个非常有用的提示。

因此,完整的解决方案是执行Session.createSQLQuery和query.SetResultTransformer

注:Transformers.AliasToBean()是所以Java。

编辑:http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/impl/SQLQueryImpl.htmlsetString()

1

你必须定义的映射关系或者做一个子查询

+0

可以向我展示子查询的示例吗? – 2010-09-21 11:49:17

+1

再次查看您的示例,您可能必须使用2个单独的查询(一个用于角色,另一个用于语言),然后在进程中linq离开外部连接。但是,这不是一个好的解决方案IMO,你应该只是在映射中定义简单的关系或者使用session.CreateSqlQuery()。 – Kelly 2010-09-21 23:12:23