entity-framework - 具有实体替换的 Doctrine 2 模块化应用程序

标签 entity-framework doctrine-orm zend-framework2

我正在使用 ZF2 和 Doctrine2 构建应用程序。 这个想法是有一个基本的应用程序实体(我们称之为 UserEntity)。

但在一个模块 A 中,我将有另一个类似 UserEntity 的实体,它将使用新字段“升级”基础实体。另一个将添加更多字段的模块 B。

例如:

基础用户实体{ protected $id; //...

ModuleAUserEntity 扩展了 BaseUserEntity { protected 模块AId;

ModuleBUserEntity 扩展了 BaseUserEntity { protected 模块B用户名;

是否有可能以某种方式获得一种方法,以便在我调用 UserEntity 时返回完整的、按模块升级的实体?例如:

用户实体{ protected $id; //... protected 模块AId; protected 模块B用户名;

还有其他方法可以实现这样的目标吗? “扩展”实体的可能性?

最佳答案

我有两种不同的方法:

1.第一个:
你应该看看: http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html

这是合法的,并且是按教义推荐的这样做的方式。

<强>2。第二个

如果你不想让 doctrine 弄乱数据库,你可以使用不同的方法:

  1. 创建一个定义所有类的通用行为的接口(interface)
  2. 编写您的基类,实现该行为。
  3. 编写您的子类、实现接口(interface)、包含新方法并包装基类的实例
  4. 您实现接口(interface)中定义的方法,但由于它们已经在父类中实现,您只需绕过对包装对象的调用即可。

所以,您正在使用 composition over inheritance避免教条(可能还有你)发疯

为了在原则上有一个真正干净的行为,我想象的数据库是:

  • 包含父实体的表
  • 一个包含子实体的表,包含
    • 具有相关父实体 ID 的外键(这是父表中包含与之关联的值的行,因为子项必须具有父项和子项字段)
    • 所有额外的列

例如:

接口(interface):

namespace DBAL\Entity;  
interface IProfesional
{
    public function setName($name);
    public function getName();
    public function getId();
}

父类:

namespace DBAL\Entity; 
use Doctrine\ORM\Mapping as ORM;

use DBAL\Entity\User\IUserAware;

/**
 * Profesional
 *
 * @ORM\Table(name="profesional")
 * @ORM\Entity
 */
class Profesional  implements IProfesional
{
    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=45, nullable=true)
     */
    private $name;
     /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * Set nombre
     *
     * @param string $nombre
     * @return Profesional
     */
    public function setName($nombre)
    {
        $this->name = $nombre;

        return $this;
    }

    /**
     * Get nombre
     *
     * @return string 
     */
    public function getNombre()
    {
        return $this->name;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return  $this->id;
    }

}

子类:

namespace DBAL\Entity; 
use DBAL\Entity\User\IUserAware;

use Doctrine\ORM\Mapping as ORM;

/**
 * Jugador
 *
 * @ORM\Table(name="jugador")
 * @ORM\Entity(repositoryClass="DBAL\Repository\JugadorRepository")
 */
class Player   implements IProfesional 
{


    /**
     * @var integer
     *
     * @ORM\Column(name="profesional_id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id; 

    /**
     * @var \Profesional
     *
     * @ORM\OneToOne(targetEntity="Profesional")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="profesional_id", referencedColumnName="id", unique=true)
     * })
     */
    private $profesional;




    /**
     * Constructor: you create an empty Profesional, 
       so you are sure you will never use a reference to an in-existent object. 
       But anyways, if this is an entity loaded from the database by doctrine,
       doctrine will fill that field whith an actual professional from the parent table,
       based in the foreign key id
     */
    public function __construct()
    {
          if(!isset($id)){
            $this->profesional=new Profesional();
        }
    }



    /**
     * Set profesional
     *
     * @param \Profesional $profesional
     * @return Jugador
      */

    public function setProfesional( Profesional $profesional = null)
    {
        $this->profesional = $profesional;

        return $this;
    }

    /**
     * Get profesional
     *
     * @return \Profesional 
    */
    public function getProfesional()
    {
        return $this->profesional;
    } 

 /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->profesional->getId();
    }



///New fields, for instance:

     /**
     * @var integer
     *
     * @ORM\Column(name="height", type="integer", nullable=true)
     */
    private $height;

    public function getHeight()
    {
        return $this->height;
    }
    public function setHeight($h)
    {
          $this->height=$h;
    }




}

关于entity-framework - 具有实体替换的 Doctrine 2 模块化应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20573173/

相关文章:

zend-framework2 - 通过 ServiceLocatorAwareInterface 注入(inject) ServiceLocator 不起作用

entity-framework - 重命名 Entity Framework 为代码优先开发生成的类

c# - EF 中的事务性 SaveChangesAsync

javascript - 从 Controller 创建 json 响应

mysql - 在 DQL 中加入并计数

zend-framework2 - 从doctrine2 ODM绑定(bind)Zend2表单数据

c# - 如何在 Entity Framework + SQL Server 中强制执行一对一关系

sql-server - 数据库恢复后 EF 不会迁移

php - 使用 Doctrine 2 在 Zend Framework 2 中进行验证

php - 使用 ZendFramework2 请求 Random.org API