用它们的FK动态设置链接属性的最佳方法是什么?


What is the best way to dynamically set a linked property with just their FK

我有很多链接属性的实体,当我处理CSV导入时,我不想为所有链接字段创建$em->getReference()调用(主要是因为我想保持它尽可能抽象,不想硬编码所有可能的引用)。

我更希望在给定属性的Entity setter方法中做到这一点。然而,这将要求我从模型内部访问原则,而这反过来又是一个糟糕的实践。

我应该访问实体的元数据,并从那里去,或者有一个更好的方法来做到这一点,我还没有提到?

在setter中这样做,真的会把整个SOA搞砸。如果你关心代码的解耦和抽象,你可以使用依赖倒置。
假设您有实体A,它与实体BC有关联,然后为了从您从CSV获得的原始数据中获得对正确BC实例的引用,您将定义两个接口,例如:BRepositoryInterfaceCRepositoryInterface,它们都可能包含单个方法find($id),但它们仍然必须不同。现在为各自的实体实现这些接口,并将它们注入创建实体A的服务中。
如果你真的想要编写一些好的代码,那么你应该创建单独的类来实现这些接口,然后将你的Doctrine repository注入其中,这些类然后作为这些repository的包装器,这样你在DataMapper层和business logic层之间就有了一个不同的层,这给了你你想要的抽象。这是我在最近对优秀代码、DDD和设计模式的研究中学到的。它远非完美(并不是说有这样的事情)。如有任何意见或建议,欢迎指教。


更新:关于你的评论:
好的设计所追求的主要目标之一是"捕捉领域专家的语言"(参见第6条)。关于这些传说中的生物的描述)。e:你的密码用简单的英语怎么说?
你的代码说的基本上是从有关联到A的实体的存储库中找到这些给定id的对象。这看起来很好,因为你没有显式依赖于A有关联。但是仔细观察,您会发现您确实依赖于实际的BC对象及其存储库,因为当您为某些对象提供 id 时,您不仅提供了id,而且还隐式地说明了该对象是什么,否则id将没有任何意义,除了它的标量值。然而,这种方法肯定在语义设计和RAD中都有它的用例。但还存在得墨忒耳定律的问题,但可以解决,见下文:
无论哪种方式,我认为你绝对应该有一个A对象的工厂,看起来像这样。

class AFactory{
  protected $br;
  protected $cr;
  public function __construct(BRepositoryInterface $br, CrepositoryInterface $cr){
    $this->br = $br;
    $this->cr = $cr;
  }
  public function create($atr1, $atr2, $bId, $cId){
    $b = $this->br->find($bId);
    $c = $this->cr->find($cId);
    return new A($atr1, $atr2, $bId, $cId);
  }
}

现在你可以使用你所说的为这个工厂创建另一个工厂的设计来创建这个工厂,这也将解决得墨忒耳定律的问题。该工厂将有Entity Manager作为它的依赖,它将读取A的元数据,并根据该元数据获取相关对象的存储库,并从这些存储库创建一个新的AFactory实例,现在如果你在实际的Doctrine存储库中实现这些接口(BRepositoryInterfaceCRepositoryInterface), AFactory实例将成功创建。