学说加入实体(Doctrine join entities)
在查询与另一个实体有关系的实体时,我正在尝试进行一些有效的改进。
实体A:
/** * @var integer * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @var string * @ORM\Column(name="name", type="string", length=225) * @Assert\NotBlank(message="Please enter a name for your profile.") */ protected $display_name; /** * @ORM\OneToOne(targetEntity="Posts", mappedBy="profile", cascade={"all"}, fetch="LAZY") */ protected $posts;
实体B:
/** * @var integer * @ORM\Column(name="profile_id", type="integer") * @ORM\Id */ protected $profile_id; /** * @ORM\OneToOne(targetEntity="Profile", inversedBy="posts") * @ORM\JoinColumn(name="profile_id", referencedColumnName="id") */ protected $profile; /** * @var string * @ORM\Column(name="content", type="string") */ protected $content;
当我计算正在执行的查询数量时,我得到两个,我猜教义是为每个实体运行两个单独的查询,即使它们有关系。
我目前正在获取实体A,如下所示:
public function fetchById($id) { return $this->createQueryBuilder('p') ->where('p.id = :id') ->setParameter('id', $id) ->getQuery() ->getOneOrNullResult(); }
然后像这样调用实体B:
$profile = $profileRepository->fetchById($user->getUserId()); $lastpost = $profile->getPosts()[0];
但我希望能够在此查询中加入第二个实体,这样我就可以调用一个查询而不是两个查询。 我希望做这样的事情:
public function fetchById($id) { return $this->createQueryBuilder('p') ->select('p','pp') ->leftJoin(Posts::class, 'pp', \Doctrine\ORM\Query\Expr\Join::WITH, 'p.id = pp.profile_id') ->where('p.id = :id') ->setParameter('id', $id) ->getQuery() ->getResults(); }
但是,左连接返回两个实体的数组。 这不是我想要的,因为我仍然希望能够在实体A中调用例如getPosts()方法。
我基本上想要填充实体A,包括所有相关实体。 但是,通过只执行一个查询而不是两个查询,这在学说中是否可行?
I'm trying to make some efficient improvements when querying for an entity which has a relationship to another entity.
Entity A:
/** * @var integer * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @var string * @ORM\Column(name="name", type="string", length=225) * @Assert\NotBlank(message="Please enter a name for your profile.") */ protected $display_name; /** * @ORM\OneToOne(targetEntity="Posts", mappedBy="profile", cascade={"all"}, fetch="LAZY") */ protected $posts;
Entity B:
/** * @var integer * @ORM\Column(name="profile_id", type="integer") * @ORM\Id */ protected $profile_id; /** * @ORM\OneToOne(targetEntity="Profile", inversedBy="posts") * @ORM\JoinColumn(name="profile_id", referencedColumnName="id") */ protected $profile; /** * @var string * @ORM\Column(name="content", type="string") */ protected $content;
When I count the number of queries being executed I get two, I guess being doctrine runs two separate queries for each entity even through they have a relationship.
I am currently fetching entity A like so:
public function fetchById($id) { return $this->createQueryBuilder('p') ->where('p.id = :id') ->setParameter('id', $id) ->getQuery() ->getOneOrNullResult(); }
And then calling entity B like so:
$profile = $profileRepository->fetchById($user->getUserId()); $lastpost = $profile->getPosts()[0];
But I want to be able to join the second entity in this query so that I can just call one query rather than two. I was hoping to do something like this:
public function fetchById($id) { return $this->createQueryBuilder('p') ->select('p','pp') ->leftJoin(Posts::class, 'pp', \Doctrine\ORM\Query\Expr\Join::WITH, 'p.id = pp.profile_id') ->where('p.id = :id') ->setParameter('id', $id) ->getQuery() ->getResults(); }
However the left join returns an array of two entities. This is not what I am wanting, because I want to still be able to call for example the getPosts() method in entity A.
I essentially want to populate entity A, including all the related entities. But by only executing one query rather than two, is this possible in doctrine?
原文:https://stackoverflow.com/questions/42749728
最满意答案
你有
DataBindingComplete
或CellFormatting
女巫可以做你想要的编辑:您还可以使用表单的Load事件仅应用一次格式
You got the
DataBindingComplete
orCellFormatting
witch could do what you wantedit : You could also use the Load event of the form to apply your formatting only once
相关问答
更多-
正确的答案是 要使用autocad模型进行某些操作,当打开无模式对话框时,锁定活动文档是必需的,在执行操作时不能以其他方式进行修改。 例如: public void CreateBlockReference (string strBlockName, Point3d Origin) { // First: lock document by next instruction DocumentLock dl = Application.DocumentManager.MdiActiveDoc ...
-
来自OP评论: 正如用户Ivan Stoev所指出的那样,并从MSDN文章中强调: 要运行示例代码,请将其粘贴到包含名为DataGridView1的[DataGridView]类型实例的项目中。 然后确保事件处理程序与[CellDoubleClick]事件关联。 正如用户OhBeWise所说 ,这可能看起来像: dataGridView1.CellDoubleClick += DataGridView1_CellDoubleClick; 要么 dataGridView1.CellDoubleClick + ...
-
DataGridView没有列(DataGridView has no columns)[2023-06-22]
我想(我完全不明白为什么)你试图访问尚不存在的列。 尝试在DataGridView.DataBindingComplete事件中移动这些代码行 FormFields.GridView.Columns[0].Width = (FormFields.GridView.Width / 10) * 6; FormFields.GridView.Columns[1].Width = (FormFields.GridView.Width / 10) * 4; I guess (I don't understand ... -
需要添加代码: dataCapPlan.ColumnHeaderMouseClick +=new DataGridViewCellMouseEventHandler(dataCapPlan_ColumnHeaderMouseClick); 请参阅post: 在DataGridView中单击行标题的事件 Needed to add code: dataCapPlan.ColumnHeaderMouseClick +=new DataGridViewCellMouseEventHandler(dataCapP ...
-
您忘记更新绘图请求,您只是定义该行而不实际绘制它 编辑: public void drawmyline() { System.Drawing.Graphics example; // Create pen. Pen blackPen = new Pen(Color.Black, 3); // Create points that define line. Point p ...
-
您可以从Form1中捕获Form2的close事件。 这真的很容易 private void new_btn_Click(object sender, EventArgs e) { var cell1 = ""; var cell2 = ""; Form2 Form2 = new Form2(cell1, cell2); Form2.FormClosed += Form2HasBeenClosed; Form2.Show(); } private void Form2 ...
-
编辑列,编辑DefaultCellStyle属性并将WrapMode属性设置为True。 并将DGV的AutoSizeRowMode更改为AllCells,以便行自动增加高度以适合文本。 列标题和单元格中的文本现在将自动自动换行。 您可以使用“\ n”强制提前换行。 Edit the column, edit the DefaultCellStyle property and set the WrapMode property to True. And change the DGV's AutoSizeRo ...
-
您的原始代码(在第一次编辑之前)看起来像这样: private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) { comboBox1.Enabled = (e.RowCount > 1); // ? true : false; } e.RowCount值报告当前正在添加的行数, 而不是在调用Add()时DataGridView中有多少行。 换句话说,如果你反复调用dataGridView1. ...
-
你有DataBindingComplete或CellFormatting女巫可以做你想要的 编辑:您还可以使用表单的Load事件仅应用一次格式 You got the DataBindingComplete or CellFormatting witch could do what you want edit : You could also use the Load event of the form to apply your formatting only once
-
从原始问题的评论: 尝试清除列 dataGridView1.Columns.Clear(); From the comments on the original question: Try clearing the columns as well dataGridView1.Columns.Clear();