NHibernate多个内部联接选择

先生

我试图让NHibernate基于3个表的内部联接做一个简单的查询:

var sessionCriteria = session.CreateCriteria<FoobarMaster>("M")
.CreateCriteria("Accounts", "A", NHibernate.SqlCommand.JoinType.InnerJoin)
.CreateCriteria("TrackingRecords", "T", NHibernate.SqlCommand.JoinType.InnerJoin)
.Add(Restrictions.Eq("T.PicNumber", "123456"));
var foobarMaster = sessionCriteria.UniqueResult<FoobarMaster>();

而在LINQ中,同样的事情:

from m in session.Query<FoobarMaster>()
from a in m.Accounts
from t in a.TrackingRecords
where t.PicNumber == "12345"
select m

使用QueryOvers和JoinAliases我也有同样的想法。总体而言,我遇到了运行时异常:

“无法解析属性:TrackingNo of:帐户”。

奇怪的TrackingNo是,它是一个TrackingRecord属性而不是一个Account属性。它甚至以T为前缀-的别名TrackingRecord

这是我的映射:

<class name="FoobarMaster" table="T_FOOBAR_MASTER">
 <id name="FoobarMasterId" column="FOOBAR_MASTER_ID" type="int">
   <generator class="identity"/></id>
 <bag name="Accounts" cascade="all" inverse="true">
   <key column="FOOBAR_MASTER_ID" />
   <one-to-many class="FoobarAccount" />
 </bag>
...

<class name="FoobarAccount" table="T_FOOBAR_ACCOUNT">
 <id name="FoobarAccountId" column="FOOBAR_ACCOUNT_ID" type="int">
   <generator class="identity"/></id>
 <many-to-one name="FoobarMaster" class="FoobarMaster" column="FOOBAR_MASTER_ID" />
 <property name="AccountId" column="ACCOUNT_ID" />
 <bag name="TrackingRecords" cascade="all" inverse="true">
   <key column="ACCOUNT_ID" />
   <one-to-many class="FoobarAccount" />
 </bag>
...

<class name="TrackingRecord" table="T_TRACKING">
 <id name="TrackingId" column="TRACKING_ID" type="int"><generator class="identity"/></id>
 <many-to-one name="FoobarAccount" class="FoobarAccount" column="ACCOUNT_ID" />
 <property name="PicNumber" column="PICNUMBER" type="AnsiString" length="25" />
 ...

这是类/实体:

public class FoobarMaster
{
 public virtual int FoobarMasterId { get; set; }
 public virtual IList<FoobarAccount> Accounts { get; set; }
...

public class FoobarAccount
{
 public virtual int FoobarAccountId { get; set; }
 public virtual FoobarMaster FoobarMaster { get; set; }
 public virtual int AccountId { get; set; }
 public virtual IList<TrackingRecord> TrackingRecords { get; set; }
...

public class TrackingRecord
{
 public virtual long TrackingId { get; set; }
 public virtual FoobarAccount FoobarAccount { get; set; }
 public virtual string PicNumber { get; set; }
...
拉迪姆·科勒

真正的问题

根据最新的问题,这里的答案很清楚,很容易解决!映射包含错误的one-to-many设置。请参阅第一级列表:

<bag name="Accounts" cascade="all" inverse="true">
  <key column="FOOBAR_MASTER_ID" />
  <!-- here we can see the CORRECT reference -->
  <one-to-many class="FoobarAccount" />
</bag>

另一方面,第二个级别具有相同的目标,这是错误的:

<bag name="TrackingRecords" cascade="all" inverse="true">
  <key column="ACCOUNT_ID" />
  <!--  WRONG. In deed, the Account does NOT contain 'PicNumber' -->
  <one-to-many class="FoobarAccount" />
</bag>

答案:

更改<one-to-many class="FoobarAccount" />
<one-to-many class="TrackingRecord" />

正确的映射应如下所示:

<bag name="TrackingRecords" cascade="all" inverse="true">
  <key column="ACCOUNT_ID" />
  <!--  now we won't recieve the Account does not contain 'PicNumber'  -->
  <one-to-many class="TrackingRecord" />
</bag>

从那一刻起,所有东西都将正常工作,问题开头的查询是正确的。无需子查询等

...

原始提示-与先前可用的信息有关

如果您的对象/实体像这样被链接起来,那么您尝试实现的目标将起作用

  1. Master有多个(或引用)帐户
  2. Account有很多(或引用)TrackingRecords

但是根据您遇到的问题,似乎您的映射是

  1. Master有多个(或引用)帐户
  2. Master有很多(或引用)TrackingRecords

在这种情况下,您只能实现SQL

select m.* from t_master m
inner join t_account a on m.master_id = a.master_id
//inner join t_tracking t on a.account_id = t.account_id
inner join t_tracking t on m.account_id = t.account_id // the m.account_id
where t.tracking_no = '123456'

查询应该是这样的:

// do some filter over A
var rootQuery = session.CreateCriteria<Master>("M")
                       .CreateCriteria("Accounts", "A", NHibernate.SqlCommand.JoinType.InnerJoin);

// working with the T here
rootQuery.CreateCriteria("TrackingRecords", "T", NHibernate.SqlCommand.JoinType.InnerJoin)
         .Add(Restrictions.Eq("T.TrackingNo", "123456"));

更新,反映问题的扩展:

此映射不适合:

TrackingRecords的关键列是ACCOUNT_ID

<class name="Account" table="T_ACCOUNT"> 
...
<bag name="TrackingRecords" cascade="all" inverse="true">
  <key column="ACCOUNT_ID" />
...

虽然TrackingRecord的引用是通过ACCOUNT_NUMBER完成的

<class name="TrackingRecord" table="T_TRACKING">
...
<many-to-one name="Account" class="Account" column="ACCOUNT_NUMBER" />
...

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用RFC选择内部联接

来自分类Dev

MariaDB更新错误内部联接并选择

来自分类Dev

使用NHibernate Linq查询无法建立内部联接

来自分类Dev

SQL从内部联接中选择计数大于

来自分类Dev

带有内部联接的递归选择

来自分类Dev

多个内部联接-MySQL

来自分类Dev

内部联接选择多个列

来自分类Dev

MySQL多个内部联接

来自分类Dev

多个内部联接返回错误

来自分类Dev

使用子查询和分组的Nhibernate内部联接的SQL

来自分类Dev

选择不同的内部联接,包括空参数

来自分类Dev

内部联接返回多个值

来自分类Dev

SQL查询-多个内部联接

来自分类Dev

JpaRepository-内部联接-后续选择

来自分类Dev

基于参数联接多个选择

来自分类Dev

使用NHibernate Linq查询无法建立内部联接

来自分类Dev

在MySQL中使用内部联接和多个选择条件创建视图

来自分类Dev

有Count的多个内部联接

来自分类Dev

使用内部联接MYSQL联接多个表

来自分类Dev

MySQL多个内部联接

来自分类Dev

NHibernate HQL内部联接(SQL Server,Visual C#)

来自分类Dev

MS Access选择多个联接

来自分类Dev

SQL多个内部联接

来自分类Dev

如何使用多个内部联接

来自分类Dev

内部联接返回多个值

来自分类Dev

MySQL优化多个内部联接

来自分类Dev

如何选择使用内部联接?

来自分类Dev

选择 DISTINCT 值,其中 where 子句在内部联接上返回多个结果

来自分类Dev

如何使用 sql 从内部联接查询中选择多个值?