Php 条令2,实体内部查询
如何在实体中执行查询Php 条令2,实体内部查询,php,filter,doctrine-orm,doctrine,Php,Filter,Doctrine Orm,Doctrine,如何在实体中执行查询 namespace Entities\Members; /** * @Entity(repositoryClass="\Entities\Member\MembersRepository") * @Table(name="Members") * @HasLifecycleCallbacks */ class Members extends \Entities\AbstractEntity { /** * @Id @Column(name="id"
namespace Entities\Members;
/**
* @Entity(repositoryClass="\Entities\Member\MembersRepository")
* @Table(name="Members")
* @HasLifecycleCallbacks
*/
class Members extends \Entities\AbstractEntity
{
/**
* @Id @Column(name="id", type="bigint",length=15)
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @Column(name="userid", type="bigint", length=26, nullable=true)
*/
protected $userid;
/**
* @Column(name="fname", type="string", length=255,nullable=true)
*/
protected $fname;
/**
* @OneToMany(targetEntity="\Entities\Users\Wall", mappedBy="entry", cascade={"persist"})
*/
protected $commententries;
public function __construct()
{
$this->commententries = new \Doctrine\Common\Collections\ArrayCollection();
}
}
示例我希望在这个实体中有一个名为:filter()
我希望能够过滤commentrients
集合。它应该返回具有特定条件的集合,例如id=1
。基本上,它应该过滤从连接查询接收的数据
比如说:
$this->commententries->findBy(array('id' => 1));
<?php
// create a new service, injecting the entitymanager. if you later wanted
// to start caching some things, you might inject a cache driver as well.
$member = $em->find('Member',$member_id); //get a member, some how.
$svc = new MemberService($em);
$favoriteCommentaries = $svc->getFavoriteCommentaries($member);
但是很明显,这是行不通的。你的问题真的很难理解,请试着在将来如何组织你的问题。例如,您说“返回相同的结果”,但说“过滤器”,这可能意味着任何事情。你想使用相同的结果集(你到底为什么会选择这样做),只使用array\u filter或array\u walk来过滤结果,还是你真的想使用条件连接?这是难以置信的模棱两可 无论如何。。回答(在阅读问题4次后)
一般来说,你不应该这样做 根据经验,实体不应该知道entitymanager(直接或通过某种中介对象) 这样做的原因主要是可测试性,但根据我的经验,它有助于以其他方式组织事情 我将通过设计一个服务类来处理查找。您的控制器(或其他什么)会像这样驱动它:
$this->commententries->findBy(array('id' => 1));
<?php
// create a new service, injecting the entitymanager. if you later wanted
// to start caching some things, you might inject a cache driver as well.
$member = $em->find('Member',$member_id); //get a member, some how.
$svc = new MemberService($em);
$favoriteCommentaries = $svc->getFavoriteCommentaries($member);
您的ArrayCollection已经实现了一个filter()方法,您需要传递一个闭包以使它在实体中工作(这里是commentEntries)
(未测试)
请注意,这种方法将迭代并快速加载您的所有评论,因此在用户有很多评论的情况下,这可能是一个很大的瓶颈
在大多数情况下,您希望使用自定义存储库,在其中可以放置此类逻辑
正如timdev所建议的,您可以创建一个MemberService,它将通过了解EntityManager来包装这样的调用
将实体与边界层分离是对原则1的一大改进,您不应该违反该规则。我同意“timdev”。您不应该在entities类中定义查询。我定义服务类的方法支持实体是存储库类。例如:用户(实体--YourBundle/entity/User.php)将拥有UserRepository(服务类--YourBundle/Repository/UserRepository.php)。你的“过滤器”方法应该在这里。您只需要在实体类中映射此服务类。在控制器中,您始终可以通过其存储库访问“过滤器”。在“使用自定义存储库进行查询”中有非常详细的记录
您不应该在实体中编写查询,但应该使用存储库来编写查询。这一点在条令文件中也有解释。它将允许您在中心位置构建自定义查询,并保持实体定义的整洁
使用条件筛选集合:
但是,如果您想在集合中使用get
方法进行筛选,您可以使用标准。您可以在条令文档中阅读如何使用标准。要按您希望的方式进行筛选,请执行以下操作:
$this->commententries->findBy(array('id' => 1));
<?php
// create a new service, injecting the entitymanager. if you later wanted
// to start caching some things, you might inject a cache driver as well.
$member = $em->find('Member',$member_id); //get a member, some how.
$svc = new MemberService($em);
$favoriteCommentaries = $svc->getFavoriteCommentaries($member);
在实体类的顶部声明条件
类
use Doctrine\Common\Collections\Criteria
在getCommentEntries
方法中,使用类进行筛选:
public function getCommentEntries()
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq('id', 1));
$filteredCommentEntries = $this->commententries->matching($criteria);
return $filteredCommentEntries;
}
你能在实体类中使用数组过滤器吗?我试过:数组过滤器($a,数组(“成员”,“入口过滤器”));但找不到类。如果要将getResult()作为模式数组返回,则可以。这就像跨过任何阵列一样。->getQuery()->getResult(2)就可以了。在php闭包中,必须用括号括起变量,例如,使用($idsToFilter),您可以使用自定义存储库来完成此操作,该存储库已使用@Entity(repositoryClass=“\Entities\Member\MembersRepository”)定义。检查我下面的答案:@deanjase我在很长时间后再次来到这里,并注意到之前不清楚您是否想要筛选您的收藏。我更新了我的答案,因为在你的集合get
方法中进行过滤是绝对可能的。虽然答案很旧,但我在过滤集合文档中发现了这样一个小注释:“你可以将集合片段的访问移到实体的专用方法中。例如,Group#getTodaysBirthdayUsers()。这显然使实体可以访问EntityManager。这是否违反了规则?@aftAbnaved将此方法添加到实体时,您不会公开EntityManager。在本例中,他们首先获取$group
来收集$userCollection
。在您的组实体中,您只需执行$this->getUsers()代码>在自定义getter中,然后添加条件逻辑。