![](/img/trans.png)
[英]How do I insert user_id with ManyToOne relationship in symfony?
[英]When batch importing, how do I fill in the field of a ManyToOne relationship?
我正在嘗試導入一批記錄(票據),但我與客戶之間存在多對一關系。 如何填寫該關系的“數據庫”列?
我在實體中使用了fromArray
的函數,我在該實體中傳遞了字段列表和一條記錄的值(數據源是CSV)。 然后在該函數內部,我只需將每個列值分配給相應的屬性。 但是,屬性Customer是一個對象,因此我需要傳遞一個我沒有的對象。
我已經考慮過將實體管理器注入到我的實體中,但這被認為是一種糟糕的做法,所以我有點受阻。
我還嘗試添加一個額外的屬性customerId
希望它會強制寫入值,但它似乎堅持使用關系值而不是屬性值。
這是我的代碼:
class Bill
/**
* @var string
*
* @ORM\Column(name="docId", type="string", length=25, nullable=false)
* @ORM\Id
*/
private $id;
/**
* @var float|null
*
* @ORM\Column(name="amount", type="float", precision=10, scale=0, nullable=true)
*/
private $amount;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Customer", inversedBy="bills")
* @ORM\JoinColumn(name="customerId", referencedColumnName="customerId", nullable=false)
*/
private $customer;
public function getCustomer(): ?Customer
{
return $this->customer;
}
public function setCustomer( $customer): self
{
$this->customer = $customer;
return $this;
}
//this is where we import
public static function fromCSVRecord($header, $line)
{
$object = new self;
foreach($header as $key => $field){
try{
switch($field){
case 'customerId':
//get the customer here from EM but we don't have EM
$customer = $em->getRepository(Customer::class)->find($line[$key]);
$object->setCustomer($customer);
break;
default:
$object->$field = $line[$key];
break;
}
}catch(\Exception $e){
dd($line[$key]);
}
}
return $object;
}
}
我希望有一種簡單的方法可以使用ORM導入記錄值,而不必將實體管理器注入到實體類中。
您的問題是您試圖將此責任歸於錯誤的班級。 您正確理解的是,您需要在實體內部需要實體管理器的巨大代碼氣味使您無法理解,因為那是執行該操作的錯誤位置。
將其移至存儲庫。 無論如何,這是一個更合乎邏輯的地方,並且您已經有了可用的實體管理器。
class BillRepository extends ServiceEntityRepository
{
//..
public function addFromCSVRecord($header, $line) {
$em = $this->getEntityManager();
$bill = new Bill();
foreach ($header as $key => $field) {
try {
switch ($field) {
case 'customerId':
$customer = $em->getRepository(Customer::class)->find($line[$key]);
// alternatively, if you are certain of the incoming data and you do not want to hit the DB...
// $customer = $this->getEntityManager()->getReference(Customer:class, $line[$key]);
$bill->setCustomer($customer);
break;
default:
$bill->$field = $line[$key];
break;
}
} catch (\Exception $e) { dd($line[$key]); }
}
// return $object;
$em->persist($bill);
$em->flush();
}
}
我不了解您在方法中發現的大部分邏輯,因為我不知道具體細節。 盡管更改了實際持久存儲數據的return
值,但是對addFromCsvRecord()
的一次調用將創建新的對象並將其持久存儲在數據庫中。
請注意,在我的答案中,我向您展示了如何使用EntityManager::getReference()
為客戶生成對象引用。 如果您可以信任輸入文件,則將稍快一些,因為您無需單擊該對象的數據庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.