PHP Symfony +一对多关系 +结果缓存

发布于 2024-09-04 13:38:40 字数 2743 浏览 4 评论 0原文

在使用 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 技术交流群。

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

发布评论

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

评论(1

你在我安 2024-09-11 13:38:40

添加新的相关记录时,您可能需要刷新记录的关系。

您可以执行以下任一操作:

$worker->refresh(true);
$worker->refreshRelated();
$worker->refreshRelated('Employer');

有关更多信息,您应该检查以下内容:
教义文档 - 刷新关系

When adding new related records, you may need to refresh the relationships of your records.

You can do either of those :

$worker->refresh(true);
$worker->refreshRelated();
$worker->refreshRelated('Employer');

For more infos you should check this :
Doctrine Documentation - Refreshing Relationships

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