我有3张桌子:
产品和网关表没有任何共同之处。没有外键等。但是当我创建产品时,我将网关选择字段显示为多选字段,其中填充了来自网关表的数据。一旦我点击提交按钮插入产品记录,那时所有选定网关的ID都会插入到mapping_product_gateways表中,并且具有相同的product_id和选定的网关ID。
因此,在插入后,记录可能如下所示:
产品表记录:
1,产品1,$ 10,数字,10/10 / 2013
2,产品2,13美元,订阅,2013年1月1日
网关表记录:
1,Paypal,03/01/2014
2,信用卡,2014年1月1日
3,2 Checking,02/01/2014
因此,mapping_product_gateways记录可能如下所示:
mapping_id,gateway_id,product_id
1,2,1
2,3,1
3,1,2
3,2,2
这意味着产品ID 1具有网关2&与之相关的3和产品ID 2具有网关1和1。 2与之相关。
由于映射和产品表之间没有直接关系,如何在存储库类中构建查询来进行搜索,插入,更新记录?或者我是否需要创建onetomany类型的关系n实体?
我完全糊涂了..对不起,但我对symfony很新。
由于
答案 0 :(得分:1)
这个问题不是一个symfony问题,而是一个学说问题。 首先,您不应该问自己"数据库将如何显示?"。更好的问题是:"产品和网关如何关联?"
据我了解你的帖子: - 许多产品可以有很多网关。
所以我们谈论的是多对多关联。这就是你需要的原因("数据库将如何显示?")第三个关联两个表的表。 但我们需要回答第二个问题("产品和网关如何关联?") 答:它们通过多对多关联来关联。
这是如何在学说中实现的?
/**
* @ORM\Entity()
*/
class Product{
/*
* @ORM\ManyToMany(targetEntity="Gateway", inversedBy="products")
*/
private $gateways;
//adder + setter + getter
}
/**
* @ORM\Entity()
*/
class Gateway{
/*
* @ORM\ManyToMany(targetEntity="Product", mappedBy="gateways")
*/
private $products;
//adder + setter + getter
}
要进行架构更新,请执行php app / console doctrine:schema:update --force in cmd(app root dir)
这就是方式,学说解决了这个问题。很好,不是吗?
你的第二个问题是:我如何与实体进行CRUD?
让我们在控制器中说出你的编码。您的数据库没有产品,但有5个网关(ids 1-5)
class someController extends Controller {
public function doSomeCrud(){
$em = $this -> get('doctrine.orm.entity_manager');
$product = new Product();
$someGateway = $em -> find('NAMESPACE\Gateway',3);
$anotherGateway = $em -> find('NAMESPACE\Gateway',5);
$product -> addGateway($someGateway) -> addGateway($anotherGateway);
$em -> persist($product);
$em -> flush();
}
}
调用该方法后,您的数据库将如下所示:
产品:1
网关:1; 2; 3; 4; 5
Product_Gateway:(1,1,3-);(2,1,5)
您可以通过
获取产品的所有网关$product -> getGateways();
并通过以下方式更新产品:
$product -> getGateways() -> first() -> setName('new name');
$em -> flush();
实体经理认识到网关3的名称已更改并生成UPDATE网关设置名称='新名称' WHERE id = 3
答案 1 :(得分:0)
您仍然缺少的是设置者和获取者(产品示例 - >网关):
public function addGateway(GatewayInterface $gateway){
$this -> gateways -> add($gateway);
return $this;
}
public function setGateways(Collection $gateway){
$this -> gateways = $gateways;
return $this;
}
public function getGateways(){
return $this -> gateways;
}
您需要先创建GatewayInterface才能使其正常工作。 而且你需要为网关提供相同的setter / getters - >产品
索引操作(创建产品)必须如下所示:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$product = new ShopProducts();
$em -> persist($product);
$gateway = new GlobalGateways();
$em -> persist($gateway);
$product -> addGateway($gateway);
$em -> flush();
}
注意:您应该始终以单数命名您的类。因此,如果名称是“Product”和“GlobalGateway”
会更好