Zend Framework 关系 - 在 findManyToManyRowset() 中定义列名?

发布于 2024-08-05 05:08:14 字数 1326 浏览 9 评论 0原文

我正在开发一个使用 Zend Framework 开发的应用程序。我已经在模型中定义了关系,并且可以愉快地使用它们,例如:

$rowset = $row->findManyToManyRowset('People', 'Jobs');

但是,我遇到了一个问题,返回的行集的列名与“People”和“Jobs”中的列名相同,因此合并了数组键,丢失最终行集中的一些数据。

我知道我可以将 Zend_Db_Select 对象传递给 findManyToManyRowset() 作为参数之一,但找不到任何解释如何在这种情况下使用它的文档,例如:

$select = $this->select()->from(array(
                                     'p' => 'people', 
                                     'j' => 'jobs'
                                     ),
                                array( 
                                     'person_id' => 'p.id',
                                     'job_id' => 'j.id',
                                     'person_code' => 'p.code',
                                     'job_code' => 'j.code'
                                     )
                                );  

如果我尝试使用上面的代码,我会收到一条消息,例如:

Error: No reference rule "" from table People to table Jobs

任何人都可以启发我如何完成此操作吗?我知道我可以更改数据库中的列名称,但我更喜欢更改代码,而不是重新设计数据库结构并更新所有相关代码。

注意:如果没有上述某种形式的列别名,返回的行集看起来像这样(即,它合并具有相同名称的列):

[_data:protected] => Array
    (
        [id] => 1
        [code] => SX342
    )

干杯,
马特

I'm working on an application developed using Zend Framework. I have defined relationships in models, and can use them happily, e.g:

$rowset = $row->findManyToManyRowset('People', 'Jobs');

However, i've hit a problem where the rowset is returned has column names that are the same in 'People' and 'Jobs', and therefore, merges the array keys, losing some of the data from the final rowset.

I understand I can pass a Zend_Db_Select object to findManyToManyRowset() as one of the parameters, but can't find any documentation explaining how to use it in this case, e.g.:

$select = $this->select()->from(array(
                                     'p' => 'people', 
                                     'j' => 'jobs'
                                     ),
                                array( 
                                     'person_id' => 'p.id',
                                     'job_id' => 'j.id',
                                     'person_code' => 'p.code',
                                     'job_code' => 'j.code'
                                     )
                                );  

If i try to use the above code, I get a message such as:

Error: No reference rule "" from table People to table Jobs

Can anyone enlighten me on how this should be done? I know I could change my column names in the database, but i'd prefer a code change as opposed to re-designing my DB structure and updating all the related code.

Note: without some form of column aliasing as above, the rowset returned looks like this (ie., it merges the columns with the same names):

[_data:protected] => Array
    (
        [id] => 1
        [code] => SX342
    )

Cheers,
Matt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ゃ人海孤独症 2024-08-12 05:08:14

我知道这个答案来得有点晚,但这里有一些事情需要指出。

1) findManyToManyRowset($matchTable, $intersectionTable, $callerRefRule, $matchRefRule, $select); -- 如果你要传递 Zend_Db_Table_Select 你会想要传递 < code>null 为规则。

2) 传入 findManyToManyRowset()Zend_Db_Table_Select 应该从 $matchTable 创建,并且可以安全地假设在 where 子句中 i 是交集表的别名,m 是匹配表的别名。

3)在发生冲突的情况下,m将赢得php返回的关联数组中的键名。执行的查询如下所示:

  SELECT 
    `i`.*, `m`.* 
  FROM 
    `interscetTable` AS `i` 
  INNER JOIN 
    `matchTable` AS `m` 
  ON
    `i`.`fk_m` = `m`.`pk` WHERE (`i`.`fk_o` = ?)  

4) 无论如何,findManyToManyRowset() 的返回值都将是从 $matchTable 创建的 Rowset,因此,如果您需要捕获相交表中的任何信息,同时还捕获匹配表的数据,您可能需要自定义 Zend_Db_Select 并避免使用 Zend_Db_Table 内容来映射数据反正。

这是一个工作示例,使用“People”作为匹配表,“Workers”作为交叉表,并假设“Clients”作为原始表。假设在这个示例中,这些表链接在一起,如下所示:
People.id:... ->工人。person_id:client_id:job_id ->客户:id:...

$client = $clientTable->fetchRow(); /// grab a random client

// fetch all people that have worked for the client ordered by their last name.
$client->findManyToManyRowset("People", "Workers", null, null, 
  $peopleTable->select()->order('m.lastname')); 

// fetch all people that have worked for the client ordered by their hire date:
// `workers`.`hiredate`
$client->findManyToManyRowset("People", "Workers", null, null, 
  $peopleTable->select()->order('i.hiredate')); 

I know this answer comes a little late but here are some things to point out.

1) findManyToManyRowset($matchTable, $intersectionTable, $callerRefRule, $matchRefRule, $select); -- if you are passing a Zend_Db_Table_Select you are going to want to pass null for the rules.

2) The Zend_Db_Table_Select passed into the findManyToManyRowset() should be created from $matchTable and it is safe to assume that in the where clauses i is the alias for the intersection table, and m is the alias for the match table.

3) In the case of collisions, m will win the key name in the associative array returned in php. The query executed looks like this:

  SELECT 
    `i`.*, `m`.* 
  FROM 
    `interscetTable` AS `i` 
  INNER JOIN 
    `matchTable` AS `m` 
  ON
    `i`.`fk_m` = `m`.`pk` WHERE (`i`.`fk_o` = ?)  

4) No matter what, The return value of findManyToManyRowset() will be a Rowset created from the $matchTable so, if you need to capture any information from the intersecting table, while also capturing the data for the match table, you will probably need to have a custom Zend_Db_Select and avoid using the Zend_Db_Table stuff to map the data anyway.

So a working example, using "People" as the match table, "Workers" as the intersection table and lets say "Clients" as the originating table.. Assuming for this example that the tables link together something like:
People.id:... -> workers.person_id:client_id:job_id -> clients:id:...

$client = $clientTable->fetchRow(); /// grab a random client

// fetch all people that have worked for the client ordered by their last name.
$client->findManyToManyRowset("People", "Workers", null, null, 
  $peopleTable->select()->order('m.lastname')); 

// fetch all people that have worked for the client ordered by their hire date:
// `workers`.`hiredate`
$client->findManyToManyRowset("People", "Workers", null, null, 
  $peopleTable->select()->order('i.hiredate')); 
挽手叙旧 2024-08-12 05:08:14

我的第一个建议是,您不应为列命名诸如 idcode 之类的通用名称。这些名称毫无意义,正如您所发现的,当您在关联数组中获取结果时,它们也会导致冲突。

您还错误地使用了“选择”界面。每次 from() 调用或 join() 调用只能指定一个表。

最后,我从不尝试通过 Zend_Db_Table 关系接口执行复杂的查询。它仅适用于简单的情况。如果您有更复杂的查询,只需显式编写 SQL 查询即可。

另请参阅如何执行ZF 表界面中的联接查询?

My first recommendation is that you shouldn't name columns such generic names like id and code. These names are meaningless, and as you have discovered they also result in collisions when you fetch results in an associative array.

You're also using the Select interface incorrectly. You should specify only one table per from() call or join() call.

Finally, I never try to do complex queries via the Zend_Db_Table relationships interface. It's intended only for simple cases. If you have a more complex query, just write the SQL query explicitly.

See also How to do a joined query in the ZF tables interface?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文