代码之家  ›  专栏  ›  技术社区  ›  Tim Lytle

Doctrine2中的自定义集合

  •  14
  • Tim Lytle  · 技术社区  · 14 年前

    this part of the documentation :

    集合值的持久字段和属性必须根据 Doctrine\Common\Collections\Collection 接口。应用程序可以使用集合实现类型在实体持久化之前初始化字段或属性。一旦实体被管理(或分离),随后的访问必须通过接口类型。

    虽然我确信这对某些人来说是非常清楚的,但我对它有点模糊。

    如果我将实体设置为初始化(例如 __construct() )将collection变量转换为实现正确接口的类-Doctrine2是否继续将该类用作集合?我理解得对吗?

    :另外,我从各种线程收集到,延迟加载中使用的占位符对象可能会影响如何使用自定义集合。

    3 回复  |  直到 14 年前
        1
  •  23
  •   romanb    14 年前

    让我试着用例子来阐明什么是可能的,什么是不可能的和计划的。

    use Doctrine\Common\Collections\Collection;
    
    // MyCollection is the "implementation type"
    class MyCollection implements Collection {
        // ... interface implementation
    
        // This is not on the Collection interface
        public function myCustomMethod() { ... }
    }
    

    现在你可以使用它如下:

    class MyEntity {
        private $items;
        public function __construct() {
            $this->items = new MyCollection;
        }
        // ... accessors/mutators ...
    }
    
    $e = new MyEntity;
    $e->getItems()->add(new Item);
    $e->getItems()->add(new Item);
    $e->getItems()->myCustomMethod(); // calling method on implementation type
    
    // $em instanceof EntityManager
    $em->persist($e);
    
    // from now on $e->getItems() may only be used through the interface type
    

    现在谈谈计划中的事情。拥有自定义集合更漂亮的方法是还拥有一个自定义接口类型,比如IMyCollection和MyCollection作为实现类型。然后,要使其与Doctrine 2持久性服务完美结合,您需要实现一个定制的PersistentCollection实现,例如MyPersistentCollection,如下所示:

    class MyPersistentCollection implements IMyCollection {
        // ...
    }
    

    然后告诉映射中的条令对该集合使用MyPersistentCollection包装器(记住,PersistentCollection) 包裹 集合实现类型,实现相同的接口,以便它可以在委托给基础集合实现类型之前/之后执行所有持久性工作)。

    因此,自定义集合实现将由3部分组成:

    1. 实现类型(实现接口类型)
    2. 持久包装器类型(实现接口类型)

    现在还不可能做到这一点,但会做到的。这是编写和使用完全定制的集合的唯一一种真正优雅且功能全面的方法,这些集合完美地集成在条令2提供的透明持久性方案中。

        2
  •  1
  •   beberlei    14 年前

    class Order
    {
        private $items;
    
        public function getTotalSum()
        {
            $total = 0;
            foreach ($this->items AS $item) {
                $total += $item->getSum();
            }
            return $total;
        }
    }
    

    然而,集合只是ORM的技术部分,它们帮助实现和管理对象之间的引用,仅此而已。

        3
  •  0
  •   Community paulsm4    7 年前

    同样的问题 here ,参考 official doctrine Jira issue 包含此“功能”的详细信息和状态的页面。。。你可以跟踪那里的发展!