首先,我将解释该解决方案的原因和工作方式,然后说明我遇到的问题。如果您认为有一种更好的方式来做我做的事,我很想听听。我也想知道为什么教义会以这种方式表现。
事实证明,我的应用程序需要根据客户端连接到其他数据库。我在固定数据库中有一个表,其中包含某些请求中使用的连接信息。 我已经成功完成了以下代码:
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();
}
我将非常感谢对此事的贡献和思想。
答案 0 :(得分:0)
代替:
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
但扩展EntityRepository
。