PHP Symfony +一对多关系 +结果缓存
在使用 Symfony 1.4 定义一对多关系时,我遇到了意想不到的行为(对我来说!)。这是一个简单的示例,演示了该行为,有一个雇主表和一个雇员表:一个雇主可以有多个雇员。 YML 架构文件如下:
Employee:
columns:
id: { type: integer, primary: true, autoincrement: true }
first_name: { type: string(30), notnull: true }
last_name: { type: string(30), notnull: true }
employer_id: { type: integer }
relations:
Employer:
local: employer_id
foreign: id
type: one
foreignType: many
foreignAlias: Workers
Employer:
columns:
id: { type: integer, primary: true, autoincrement: true }
name: { type: string(100) }
line1: { type: string(100) }
city: { type: string(100) }
state: { type: string(10) }
因此,在雇主上调用 getWorkers() 应返回与雇主关联的员工。第一次调用 getWorkers() 时,我得到了预期的行为。
但是,在后续调用中,如果已向雇主添加其他员工(以编程方式或直接在数据库 [MySQL] 中),getWorkers()
调用仍会返回第一个结果。
我通过单步执行 getWorkers()
调用的 Symfony 源代码来验证,在后续调用中,它会返回存储在 _references
数组中的缓存值。
如果我以编程方式跟踪外键,通过 employee_id
查询 Employee
,那么我将获得完整的结果集。
谁能解释这种行为?
下面是我在“操作”中运行的一些示例 PHP 代码,它演示了该行为:
// Create common employer.
$employer = new Employer();
$employer->setName("My Employer");
$employer->setLine1("100 Main Street");
$employer->setCity("AnyTown");
$employer->setState("State");
$employer->save();
// Create two employees,
$worker1 = new Employee();
$worker1->setFirstName("John");
$worker1->setLastName("Doe");
$worker1->setEmployer($employer);
$worker1->save();
$worker2 = new Employee();
$worker2->setFirstName("Jane");
$worker2->setLastName("Smith");
$worker2->setEmployer($employer);
$worker2->save();
$myEmployer = Doctrine_Core::getTable('Employer')->findOneBy('name', 'My Employer');
$workers = $myEmployer->getWorkers();
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This gives the expected 2 employees.
// Now create another employee in the common employer.
$worker3 = new Employee();
$worker3->setFirstName("Anne");
$worker3->setLastName("Droid");
$worker3->setEmployer($employer);
$worker3->save();
$myEmployer = Doctrine_Core::getTable('Employer')->findOneBy('name', 'My Employer');
$workers = $myEmployer->getWorkers();
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This still gives 2 employees, whereas there are 3 in the DB.
// Follow FK directly.
$workers = Doctrine_Core::getTable('Employee')->findBy('employer_id', $myEmployer->getId());
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This gives the expected 3 employees.
How do I强制它每次都重新遵循关系?
I am getting unexpected behavior (to me!) when defining a one-to-many relationship with Symfony 1.4. Here is a simple example which demonstrates the behavior, having an Employer table and an Employee table: one Employer can have many Employees. The YML schema file is as follows:
Employee:
columns:
id: { type: integer, primary: true, autoincrement: true }
first_name: { type: string(30), notnull: true }
last_name: { type: string(30), notnull: true }
employer_id: { type: integer }
relations:
Employer:
local: employer_id
foreign: id
type: one
foreignType: many
foreignAlias: Workers
Employer:
columns:
id: { type: integer, primary: true, autoincrement: true }
name: { type: string(100) }
line1: { type: string(100) }
city: { type: string(100) }
state: { type: string(10) }
Thus, calling getWorkers()
on an Employer should return the Employees associated w/ the Employer. I get this expected behavior when getWorkers()
is called the first time.
However, on subsequent calls, if additional employees have been added to the employer (either programmatically or directly in the DB [MySQL]), the getWorkers()
call still returns the first results.
I've verified by stepping through the Symfony source for the getWorkers()
call that, on the subsequent calls, it's returning the cached value stored in the _references
array.
If I follow the foreign key programmatically, querying Employee
by employee_id
, then I get the full result set.
Can anyone explain this behavior?
Here's some example PHP code that I run in an 'action', which demonstrates the behavior:
// Create common employer.
$employer = new Employer();
$employer->setName("My Employer");
$employer->setLine1("100 Main Street");
$employer->setCity("AnyTown");
$employer->setState("State");
$employer->save();
// Create two employees,
$worker1 = new Employee();
$worker1->setFirstName("John");
$worker1->setLastName("Doe");
$worker1->setEmployer($employer);
$worker1->save();
$worker2 = new Employee();
$worker2->setFirstName("Jane");
$worker2->setLastName("Smith");
$worker2->setEmployer($employer);
$worker2->save();
$myEmployer = Doctrine_Core::getTable('Employer')->findOneBy('name', 'My Employer');
$workers = $myEmployer->getWorkers();
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This gives the expected 2 employees.
// Now create another employee in the common employer.
$worker3 = new Employee();
$worker3->setFirstName("Anne");
$worker3->setLastName("Droid");
$worker3->setEmployer($employer);
$worker3->save();
$myEmployer = Doctrine_Core::getTable('Employer')->findOneBy('name', 'My Employer');
$workers = $myEmployer->getWorkers();
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This still gives 2 employees, whereas there are 3 in the DB.
// Follow FK directly.
$workers = Doctrine_Core::getTable('Employee')->findBy('employer_id', $myEmployer->getId());
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This gives the expected 3 employees.
How do I force it to re-follow the relation every time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
添加新的相关记录时,您可能需要刷新记录的关系。
您可以执行以下任一操作:
有关更多信息,您应该检查以下内容:
教义文档 - 刷新关系
When adding new related records, you may need to refresh the relationships of your records.
You can do either of those :
For more infos you should check this :
Doctrine Documentation - Refreshing Relationships