2011-12-31 73 views
1

我的目标是有可能通过用户名和姓氏以及通过录入年和学期搜索文档。 文件只与声明有关,以便文件与一个声明连接一个声明和声明可以很好地连接到一个或一个文件。Yii框架 - 通过相同的“通过”表的两个关系

声明与OutgoingStudent和Recrutation有关。

所以当查询文件我想通过声明表查询OutgoingStudent和Recrutations。

我在文档中的关系码:

return array(
         'declaration' => array(self::BELONGS_TO, 'Declaration', 'DeclarationID'), 
      'outgoingStudentUserIdUser' => array(self::HAS_ONE, 'OutgoingStudent', 'OutgoingStudent_User_idUser','through'=>'declaration',), 
       'Recrutation' => array(self::HAS_ONE, 'Recrutation', 'Recrutation_RecrutationID','through'=>'declaration'), 
       ); 

现在当搜索()函数,我要打一个查询 - >与

'declaration','outgoingStudentUserIdUser' and 'Recrutation': 

       $criteria->with = array('declaration','Recrutation','outgoingStudentUserIdUser'); 

我得到这个错误:

CDbCommand nie zdołał wykonać instrukcji SQL: SQLSTATE[42000] [1066] Not unique table/alias: 'declaration'. The SQL statement executed was: SELECT COUNT(DISTINCT t . DeclarationID) FROM Documents t LEFT OUTER JOIN Declarations declaration ON (t . DeclarationID = declaration . idDeclarations) LEFT OUTER JOIN Recrutation Recrutation ON (declaration . Recrutation_RecrutationID = Recrutation . RecrutationID) LEFT OUTER JOIN Declarations declaration ON (t . DeclarationID = declaration . idDeclarations) LEFT OUTER JOIN OutgoingStudent outgoingStudentUserIdUser ON (declaration . OutgoingStudent_User_idUser = outgoingStudentUserIdUser . User_idUser)

仅使用$criteria->with = array('declaration','Recrutation')$criteria->with = array('declaration','outgoingStudentUserIdUser')只有在使用b OTH。

所以可能它应该以其他方式完成,但怎么做?

回答

2

我有很多事情要告诉你!在这里他们是:

我发现你的关系函数声明很杂乱,我不确定它是否正在做你想做的事情(如果它工作的话)。这里有我的建议重新申报:

首先,'outgoingStudentUserIdUser'看起来像一个关系的可怕的名字。最后,这个关系将会针对outgoingStudentUser的实例,而不仅仅是'id'。所以让我把它命名为outgoingStudentUser。现在,这是我的代码:

'outgoingStudentUser' => array(self::HAS_ONE, 'OutgoingStudent', array('idDocuments'=>'idOutgoingStudent'),'through'=>'declaration',), 

其中“idDocuments”是文档模式的主键,idOutgoingStudent是OutgoingStudent模型的主键。

第二个关系可以以非常相似的方式进行修正:

'Recrutation' => array(self::HAS_ONE, 'Recrutation', array('idDocuments'=>'idRecrutation'),'through'=>'declaration'), 

其中“idDocuments”是文档模式的主键,idRecrutation是Recrutation模型的主键。

你可以发现,这是正确的声明在这里:http://www.yiiframework.com/doc/guide/1.1/en/database.arr#through-on-self

但是这还不是全部。我有更多要告诉你!你用你的代码做什么是毫无意义的。 'with'用于强制加载相关对象。在下面的代码:

$criteria->with = array('declaration','Recrutation','outgoingStudentUserIdUser'); 

你只是规定在$标准,当你在数据库检索使用此$标准文件的实例,它也将获取由作为通过关系联系到该实例的模型参数设置为'with'。这是急切的加载。它用于减少对数据库的查询次数。就像是说:“去数据库并拿到我这个文档的实例,但是一旦你到达那里,就为所有与这个对象相关的其他表格的实例带来一次。”

嗯,这就是你所声明的,但肯定这不是你想要做的。我如何知道?因为该声明在search()函数中是无用的。正如你在这里看到的:http://www.yiiframework.com/doc/api/1.1/CDbCriteria/#with-detail,'with'只在某些函数中有用,而search()不是其中的一个。在搜索内部(),急切的加载是毫无意义的,毫无意义和无用的。

所以我看到自己被迫问你你想做什么?你说:“我的目标是有可能通过用户名和姓氏以及通过录入年和学期来搜索文档”,但是,“通过用户名和...搜索文档”是什么意思?你想要这样的东西:$ user-> documents,返回与$ user相关的所有文档?我希望你能更具体一些,但也许在另一个更具针对性的问题上。

+0

感谢您的意见!我试图实现的目标是在CGridView中显示文档(例如:show(在CGridView中)显示属于recrutation id 1且由用户创建的所有文档的Recrutations数据和Outgoing Students数据(姓名和姓名)约翰·史密斯)。在搜索()中使用“with”的想法不是我的 - 我在这里找到它:http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/ – Pax0r 2012-01-03 20:02:24

+0

原来如此!是的,这是我的错。现在,你是否尝试了我的建议?它有用吗? – 2012-01-03 21:56:00

+0

我已经手写了一个SQL,但仍然使用了一些一般的技巧,所以我接受你的答案 – Pax0r 2012-01-09 23:07:56

0

你也可以试试这个:

return array(
      'declaration' => array(self::BELONGS_TO, 'Declaration', 'DeclarationID'), 
      'outgoingStudentUserIdUser' => array(self::HAS_ONE, 'OutgoingStudent', 'OutgoingStudent_User_idUser','through'=>'declaration',), 
      'Recrutation' => array(self::HAS_ONE, 'Recrutation', '', 'on'=>'declaration.id=Recrutation.Recrutation_RecrutationID'), 
);