多对多关系的原则约束
Doctrine Constraint on a Many-to-Many Relation
我们有一个实体 'User',它与不同的 'Types' 具有多对多关系。 MySQL 关系是通过交叉 Table.
处理的
class User {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Type")
* @ORM\JoinTable(name="user_type",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")}
* )
*/
protected $types;
}
class Type {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\User")
* @ORM\JoinTable(name="user_type",
* joinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
* )
*/
protected $users;
/**
* @ORM\Column(type="datetime")
*/
protected $publishedAt;
}
如何将这种多对多关系中的响应限制为仅显示已发布的类型?
那是事实SQL 应该包括一个WHERE
来过滤尚未发布的相应项目。我可以用注释或类似的东西来做到这一点吗?
我知道我可以通过过滤返回的集合来做到这一点。但是还有比这更有效的吗?
这个问题有点重复。
这里已经回答了:php - Doctrine2 association mapping with conditions - Stack Overflow
其中一条评论指出,这会导致多对多关系错误。从 Doctrine 2.5 开始,情况不再如此。
所以你可以在学说中做的是在请求关系的实体时交出查询条件:
所以您不更改 注释,而是更改实体的 getter:
class User {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Type")
* @ORM\JoinTable(name="user_type",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")}
* )
*/
protected $types;
public function getTypes()
{
$criteria = Criteria::create()->where(Criteria::expr()->lte('publishedAt', date('Y-m-d')));
return $this->types->matching($criteria);
}
}
这将导致所需项目的延迟获取(取决于您的设置)。所有的教义魔法仍然有效,比如缓存之类的。所以集合只会被取回,如果没有被取回...
您可以使用 Criteria
。
向您的 User
class 添加一个名为 getPublishedTypes
.
的函数
public function getPublishedTypes()
{
return $this->getTypes()->matching(TypeRepository::createPublishedCriteria());
}
然后在您的 TypeRepository
中添加函数 createPublishedCriteria
。
static public function createPublishedCriteria()
{
return Criteria::create()
->andWhere(Criteria::expr()->lte('publishedAt', date('Y-m-d')); //your logic
}
注意: 函数必须是静态的
您也可以稍后在您的查询构建器中使用该条件,并使用以下行
$qb->addCriteria(self::createPublishedCriteria())
.
另一种有不良做法的解决方案可能是集合过滤。添加您的用户 class:
public function getPublishedTypes()
{
return $this->getTypes()->filter(function(Type $type) {
return $type->getPublishedAt < date('Y-m-d');
}
这个版本不是很好,因为它会产生更多的查询(对数据库中的大数据不利)。
我们有一个实体 'User',它与不同的 'Types' 具有多对多关系。 MySQL 关系是通过交叉 Table.
处理的class User {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Type")
* @ORM\JoinTable(name="user_type",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")}
* )
*/
protected $types;
}
class Type {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\User")
* @ORM\JoinTable(name="user_type",
* joinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
* )
*/
protected $users;
/**
* @ORM\Column(type="datetime")
*/
protected $publishedAt;
}
如何将这种多对多关系中的响应限制为仅显示已发布的类型?
那是事实SQL 应该包括一个WHERE
来过滤尚未发布的相应项目。我可以用注释或类似的东西来做到这一点吗?
我知道我可以通过过滤返回的集合来做到这一点。但是还有比这更有效的吗?
这个问题有点重复。 这里已经回答了:php - Doctrine2 association mapping with conditions - Stack Overflow
其中一条评论指出,这会导致多对多关系错误。从 Doctrine 2.5 开始,情况不再如此。
所以你可以在学说中做的是在请求关系的实体时交出查询条件:
所以您不更改 注释,而是更改实体的 getter:
class User {
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Type")
* @ORM\JoinTable(name="user_type",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")}
* )
*/
protected $types;
public function getTypes()
{
$criteria = Criteria::create()->where(Criteria::expr()->lte('publishedAt', date('Y-m-d')));
return $this->types->matching($criteria);
}
}
这将导致所需项目的延迟获取(取决于您的设置)。所有的教义魔法仍然有效,比如缓存之类的。所以集合只会被取回,如果没有被取回...
您可以使用 Criteria
。
向您的 User
class 添加一个名为 getPublishedTypes
.
public function getPublishedTypes()
{
return $this->getTypes()->matching(TypeRepository::createPublishedCriteria());
}
然后在您的 TypeRepository
中添加函数 createPublishedCriteria
。
static public function createPublishedCriteria()
{
return Criteria::create()
->andWhere(Criteria::expr()->lte('publishedAt', date('Y-m-d')); //your logic
}
注意: 函数必须是静态的
您也可以稍后在您的查询构建器中使用该条件,并使用以下行
$qb->addCriteria(self::createPublishedCriteria())
.
另一种有不良做法的解决方案可能是集合过滤。添加您的用户 class:
public function getPublishedTypes()
{
return $this->getTypes()->filter(function(Type $type) {
return $type->getPublishedAt < date('Y-m-d');
}
这个版本不是很好,因为它会产生更多的查询(对数据库中的大数据不利)。