symfony - 使用自定义存储库时,动态 EntityManager find() 方法返回“未找到表”
问题描述
首先,我将解释解决方案的工作原理和方式,然后解释我遇到的问题。如果您认为有更好的方法来做我所做的事情,我很想听听。我也想知道为什么教义会这样。
事实证明,我的应用程序需要根据客户端连接到不同的数据库。我有一个固定数据库中的表,其中包含在某些请求中使用的连接信息。我使用以下代码取得了成功:
class DynamicEntityManager {
protected $em;
private $request;
private $client_id;
public function __construct(RequestStack $request, EntityManagerInterface $em){
$this->em = $em;
$this->request = $request;
}
public function getEntityManager(ClientConn $client = null) {
$request = $this->request->getCurrentRequest();
if($client == NULL){
$domain = $request->attributes->get('domain');
if($domain == "" || $domain == NULL){
throw new \Exception("Error de conexion", 1);
}
$client = $this->em->getRepository(ClientConn::class)->findOneBy(array(
"subdomain" => $domain
));
if($client == NULL){
throw new \Exception("Error de conexion", 1);
}
}
$connectionDB = $client->getConnection();
$dbdriver = 'oci8';
$conexionSplit = explode(':',$connectionDB);
$dbhost = $conexionSplit[0];
$dbport = $conexionSplit[1];
$dbname = $conexionSplit[2];
$dbuser = $client->getUsuarioBd();
$dbpass = $client->getClaveBd();
$service = false;
$this->client_id = $client->getId();
if(strpos($dbname,'SN=') !== false){
$parts = explode('=',$dbname);
$dbname = $parts[1];
$service = true;
}
$request->attributes->set('client_id',$client->getId());
$conn = array(
'driver' => $dbdriver,
'host' => $dbhost,
'port' => $dbport,
'dbname' => $dbname,
'user' => $dbuser,
'password' => $dbpass,
'service' => $service,
'charset' => 'UTF8',
'schema' => null
);
return EntityManager::create($conn, $this->em->getConfiguration());
}
}
如您所见,我使用新连接返回EntityManager::create($conn, $this->em->getConfiguration ())。我使用它的方式是下一个:
/**
* @Route("/api/client/{id}/conf/{confID}", name="conf.show")
* @Method({"GET"})
*/
public function show(ClientConn $client, Request $request, DynamicEntityManager $dem ,$confId){
try {
$em = $dem->getEntityManager($client);
$entity = $em->getRepository(Configuration::class)->find($confId);
return new JsonResponse($entity, 200);
}
catch(\Exception $ex) {
return new JsonResponse([
"excepcion" => $ex->getMessage()
], $ex->getCode());
}
}
它按预期工作,或者我相信直到我看到当实体具有自定义存储库时它无法使用动态连接,因此之前的路由将返回一个未找到表的异常。
- @ORM\Entity() <-- 像魅力一样工作
- @ORM\Entity(repositoryClass="App\Repository\ConfigurationRepository")<-- 找不到表。
如果我再次创建连接,它可以在存储库中工作,尽管我不喜欢这个解决方案。那么,我想要什么?我希望能够使用 find()、findBy() 等基本方法,而不必每次使用自定义存储库时都重写它们。
class ConfigurationRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry, DynamicEntityManager $dem)
{
parent::__construct($registry, Configuration::class);
$this->dem= $dem;
}
public function uglyFind($client, $confID)
{
$query = $this->dem->getEntityManager($client)->createQueryBuilder('conf')
->select("conf")
->from(ConfPedidosLentes::class,'conf')
->where('conf.id = :value')->setParameter('value', $confID)
->getQuery();
return $query->getOneOrNullResult();
}
我将非常感谢在这件事上的任何贡献和想法。
解决方案
代替:
class ConfigurationRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry, DynamicEntityManager $dem)
{
parent::__construct($registry, Configuration::class);
$this->dem= $dem;
}
...
尝试扩展 EntityRepository (不使用构造函数)并像在控制器中那样使用 find :
use Doctrine\ORM\EntityRepository;
class ConfigurationRepository extends EntityRepository
{
}
ServiceEntityRepository
是一个可选的EntityRepository
基类,具有用于自动装配的简化构造函数,它将实体管理器显式设置为EntityRepository
基类。由于您没有配置您的学说管理器来正确处理这些连接(实际上甚至不可能有这么多的连接),ServiceEntityRepository
会将错误的 EntityManager 实例传递给EntityRepository
子类,这就是您不应该扩展ServiceEntityRepository
but的原因EntityRepository
。
推荐阅读
- php - 如何为 Eloquent 设置现有连接
- regex - VBA Excel中正则表达式中的文本替换
- java - 根据当前请求 URI 获取用户的权限
- android - DatePickerDialog 月份显示为数字(Jan 为 1)
- flutter - 无法使用 firebase_messaging 在 iOS 上的 Flutter 应用中订阅主题
- c# - 使用反射获取类列表的类成员
- c++ - 调试c++时如何在vscode中添加额外的源目录
- javascript - 在 Javascript 中重新格式化字符串
- laravel - 为什么获取数据在刀片中不起作用但在 dd 时起作用?
- angular - 改变了角材料的进口