Doctrine ORM Fatal error: Uncaught Doctrine\ORM\Query\QueryException - orm

I am trying out doctrine using this tutorial. https://www.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html. The issue is, when passing the DQL statement to the Create Query method, I get the error below.
Fatal error: Uncaught Doctrine\ORM\Query\QueryException: SELECT b, e, r FROM Bug b JOIN b.engineer e JOIN b.reporter r ORDER BY b.created DESC in
Here are the code:
$dql = "SELECT b, e, r FROM Mimoh\Gtcsl\entity\Bug::class b JOIN b.engineer e JOIN
b.reporter r ORDER BY b.created DESC";
$query = $entityManager->createQuery($dql);
$query->setMaxResults(12);
$bugs = $query->getResult();
But when I when I specify the class name, the code works. Here is the working code.
use Mimoh\Gtcsl\entity\Bug;
$dql = "SELECT b, e, r FROM " . Bug::class . " b JOIN b.engineer e JOIN
b.reporter r ORDER BY b.created DESC";
and this also works:
$bug = Mimoh\Gtcsl\entity\Bug;
$dql = "SELECT b, e, r FROM $bug b JOIN b.engineer e JOIN
b.reporter r ORDER BY b.created DESC";
I kind of know these might not be the proper way. Please any help will be highly appreciated.

Related

Linq to Entities eqiuvalent to a filtered inline view in T-SQL

I have a query from a database I need to make. I understand how to write the query in T-SQL. The real query is much more complicated, but a simple illustration of the pattern is something like this:
SELECT * FROM [dbo].[A] AS a
LEFT JOIN dbo.[B] AS b ON a.ID = b.ParentID
LEFT JOIN dbo.[C] AS c ON y.ID = c.ParentID
LEFT JOIN
(
SELECT * FROM dbo.[D]
WHERE OtherID = #otherID
) AS d ON c.ID = d.ParentID
LEFT JOIN
(
SELECT * FROM dbo.[E]
WHERE OtherID = #otherID
) AS e ON e.ID = e.ParentID
WHERE A.ID = #Id
I need to write that SQL in C# linq to sql (for entityframework core) such that it generates the equivalent of the filtered inline views above. The goal obviously is to return a result set that always contains the tree A->B->C and contains D or E if and only if those nodes also match the secondary filtering. Note that it is quite easy to do the filtering within the inline view, but very difficult to do it outside the inline view because filtering outside the inline view tends to cause C nodes to disappear when there is no matching D child. That is not the intention.
Thanks
PS: To clarify, you might make a first attempt to write the above as:
query = from a in context.A
join bt in context.B on a.ID equals bt.ParentID into btent
from b in btent.DefaultIfEmpty()
join ct in context.C on b.ID equals ct.ParentID into ctent
from c in ctent.DefaultIfEmpty()
join dt in context.D on c.ID equals dt.ParentID into dtent
from d in dtent.DefaultIfEmpty()
.Include(a => a.B).ThenInclude(b => b.C).ThenInclude(c => c.D)
.Where(a => a.ID = myPrimaryID && d.OtherId = myOtherID)
The trouble is that a where clause on the 'd' entity returns only those rows where D entity exists, so the entire stack will be empty if it isn't. If you try to get cute and say filter where the 'd' entity is null or matches the filter, if you inspect the sql generated by EF in that situation, it is incorrect. The correct filtering has to happen within the 'join', as with the T-SQL above.
PPS: Yes, if you aren't filtering except for the parent object, you can dispense with this entirely and just write the includes and the where clause, but I think on reflection you'll realize that filtering by a term that applies to a great-grand-child but doesn't filter the grand-child is complex. If you can write out the query in either 'form', I'd appreciate it.
Apart from the lack of natural left outer join syntax, select being last, and select * requires anonymous/concrete type projection (but it could contain whole entities), LINQ supports the same constructs as standard SQL, including inline subqueries.
So it's possible to write LINQ query the exact way as sample SQL query:
from a in db.A
join b in db.B on a.ID equals b.ParentID
into a_b from b in a_b.DefaultIfEmpty()
join c in (from c in db.C where c.OtherID == myOtherID select c) on b.ID equals c.ParentID
into b_c from c in b_c.DefaultIfEmpty()
join d in (from d in db.D where d.OtherID == myOtherID2 select d) on c.ID equals d.ParentID
into c_d from d in c_d.DefaultIfEmpty()
select new { a, b, c, d }
which is translated by EF Core to:
SELECT [s].[ID], [s0].[ID], [s0].[ParentID], [t].[ID], [t].[OtherID], [t].[ParentID], [t0].[ID], [t0].[OtherID], [t0].[ParentID]
FROM [SO6_A] AS [s]
LEFT JOIN [SO6_B] AS [s0] ON [s].[ID] = [s0].[ParentID]
LEFT JOIN (
SELECT [s1].[ID], [s1].[OtherID], [s1].[ParentID]
FROM [SO6_C] AS [s1]
WHERE [s1].[OtherID] = #__myOtherID_0
) AS [t] ON [s0].[ID] = [t].[ParentID]
LEFT JOIN (
SELECT [s2].[ID], [s2].[OtherID], [s2].[ParentID]
FROM [SO6_D] AS [s2]
WHERE [s2].[OtherID] = #__myOtherID2_1
) AS [t0] ON [t].[ID] = [t0].[ParentID]
Another standard LINQ way is to push the predicates into join conditions (thus not filtering out the outer join result) by using composite join keys:
from a in db.A
join b in db.B on a.ID equals b.ParentID
into a_b from b in a_b.DefaultIfEmpty()
join c in db.C on new { K1 = b.ID, K2 = myOtherID } equals new { K1 = c.ParentID, K2 = c.OtherID }
into b_c from c in b_c.DefaultIfEmpty()
join d in db.D on new { K1 = c.ID, K2 = myOtherID2 } equals new { K1 = d.ParentID, K2 = d.OtherID }
into c_d from d in c_d.DefaultIfEmpty()
select new { a, b, c, d }
which is translated to:
SELECT [s].[ID], [s0].[ID], [s0].[ParentID], [s1].[ID], [s1].[OtherID], [s1].[ParentID], [s2].[ID], [s2].[OtherID], [s2].[ParentID]
FROM [SO6_A] AS [s]
LEFT JOIN [SO6_B] AS [s0] ON [s].[ID] = [s0].[ParentID]
LEFT JOIN [SO6_C] AS [s1] ON ([s0].[ID] = [s1].[ParentID]) AND (#__myOtherID_0 = [s1].[OtherID])
LEFT JOIN [SO6_D] AS [s2] ON ([s1].[ID] = [s2].[ParentID]) AND (#__myOtherID2_1 = [s2].[OtherID])
More compact LINQ way is to use correlated sub queries instead of joins:
from a in db.A
from b in db.B.Where(b => a.ID == b.ParentID).DefaultIfEmpty()
from c in db.C.Where(c => b.ID == c.ParentID && c.OtherID == myOtherID).DefaultIfEmpty()
from d in db.D.Where(d => c.ID == d.ParentID && d.OtherID == myOtherID2).DefaultIfEmpty()
select new { a, b, c, d }
which is happily translated by EF Core to:
SELECT [s].[ID], [s0].[ID], [s0].[ParentID], [t].[ID], [t].[OtherID], [t].[ParentID], [t0].[ID], [t0].[OtherID], [t0].[ParentID]
FROM [SO6_A] AS [s]
LEFT JOIN [SO6_B] AS [s0] ON [s].[ID] = [s0].[ParentID]
LEFT JOIN (
SELECT [s1].[ID], [s1].[OtherID], [s1].[ParentID]
FROM [SO6_C] AS [s1]
WHERE [s1].[OtherID] = #__myOtherID_0
) AS [t] ON [s0].[ID] = [t].[ParentID]
LEFT JOIN (
SELECT [s2].[ID], [s2].[OtherID], [s2].[ParentID]
FROM [SO6_D] AS [s2]
WHERE [s2].[OtherID] = #__myOtherID2_1
) AS [t0] ON [t].[ID] = [t0].[ParentID]
Finally, the most compact and preferred way in EF Core is to use navigation properties instead of manual joins in LINQ to Entities query:
from a in db.A
from b in a.Bs.DefaultIfEmpty()
from c in b.Cs.Where(c => c.OtherID == myOtherID).DefaultIfEmpty()
from d in c.Ds.Where(d => d.OtherID == myOtherID2).DefaultIfEmpty()
select new { a, b, c, d }
which is also translated by EF Core to:
SELECT [s].[ID], [s0].[ID], [s0].[ParentID], [t].[ID], [t].[OtherID], [t].[ParentID], [t0].[ID], [t0].[OtherID], [t0].[ParentID]
FROM [SO6_A] AS [s]
LEFT JOIN [SO6_B] AS [s0] ON [s].[ID] = [s0].[ParentID]
LEFT JOIN (
SELECT [s1].[ID], [s1].[OtherID], [s1].[ParentID]
FROM [SO6_C] AS [s1]
WHERE [s1].[OtherID] = #__myOtherID_0
) AS [t] ON [s0].[ID] = [t].[ParentID]
LEFT JOIN (
SELECT [s2].[ID], [s2].[OtherID], [s2].[ParentID]
FROM [SO6_D] AS [s2]
WHERE [s2].[OtherID] = #__myOtherID2_1
) AS [t0] ON [t].[ID] = [t0].[ParentID]
Fair enough. 99.9% percent of EF questions about translating LEFT JOIN are a simple failure to use Navigation Properties.
EF Core is adding filtered includes in the next version see Filtering on Include in EF Core.
Or you can project A, along with selected child collections something like this:
var q = from a in db.A
select new
{
a,
Bs = a.Bs,
Ds = a.Bs.SelectMany( b => b.Ds ).Where(d => d.OtherID = dOtherId)
};

I get this error when accessing a website"Error while accessing the database You have an error in your SQL syntax"

I keep getting this error:
"Error while accessing the database
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
select count(*)
from course_catalog cc
INNER JOIN classes c ON cc.course_id = c.course_id
INNER JOIN reservation r ON c.class_id = r.class_id
where r.student_id ="
How can i fix it?
" is not a valid identifier. It seems likes you're supposed to pass a student id (an integer) to be compared with r.student_id.
You have " in the end of the sql query. Make your query properly by providing appropriate condition.
Change the last part, adding a value to compare against.
For example, against 123:
select count(*)
from course_catalog cc
INNER JOIN classes c ON cc.course_id = c.course_id
INNER JOIN reservation r ON c.class_id = r.class_id
where r.student_id = 123
Or against null:
select count(*)
from course_catalog cc
INNER JOIN classes c ON cc.course_id = c.course_id
INNER JOIN reservation r ON c.class_id = r.class_id
where r.student_id is null

Symfony sql request

i'm performing an sql request, but in that request I would like to get all the field from the mission table...but if I write m.* inside the select...symfony told me the Mission entity doesn't have any * field. How can I translate that without getting all the field...because I got more or less 40 field in that table so...Thanks
$sql="SELECT v.id,v.codeVague, v.date_fin_ultime
FROM McInvestigatorBundle:Vague v
INNER JOIN McInvestigatorBundle:Enquete e WITH e.vague_id = v.id
INNER JOIN McInvestigatorBundle:Mission m WITH m.id = e.mission_id
INNER JOIN McInvestigatorBundle:Contrat c WITH c.id = m.contrat
INNER JOIN McInvestigatorBundle:User u WITH u.enqueteur_id = e.enqueteur_id
INNER JOIN McInvestigatorBundle:PointDeVente p WITH p.id = e.pdv_id
WHERE v.codeVague =".$wave_code."
AND e.type_id =".$type_id."
AND m.enqueteur_id=".$enq_id;
Just try it with:
SELECT v.id,v.codeVague, v.date_fin_ultime, m
FROM McInvestigatorBundle:Vague v

Hibernate hql query

How can i express this SQL query in HQL if we say i have the correct mappings, dtos(pojo) and configurations files...
select * from sig_tc_contraloria_objetivos o
inner join sig_tc_contraloria_iniciativas i on o.id_objetivo = i.id_objetivo
inner join sig_tc_contraloria_acciones a on i.id_iniciativa = a.id_iniciativa
where a.id_organizacion = 8;
I expect as a result a List of objetivos(Parent) -> Iniciativas(Child) -> Acciones(Child)
I was trying in this way:
String sql = "select distinct p from SigTcContraloriaObjetivos p join p.children c join c.children b where b.idOrganizacion = 8";
assuming correct mapping and configuration the following should work
String sql = "select distinct p from SigTcContraloriaObjetivos p join p.children c join c.children b where b.idOrganizacion = 8";
the difference is in the where clause. You had an and right after where and that's illegal syntax.

linq2sql with group and joins

How would one write this query in linq (VB)
select
g.*
from PROB_GROUP g
inner join
(
select
PGR_NAME,
PGR_PCELL,
max(PGR_VERSION) max_version
from PROB_GROUP
group by PGR_NAME, PGR_PCELL
) grouped_g
on g.PGR_NAME = grouped_g.PGR_NAME
and g.PGR_PCELL = grouped_g.PGR_PCELL
and g.PGR_VERSION = grouped_g.max_version
order by g.PGR_TYPE, g.PGR_NAME
got it
From pp In DB.PROB_GROUPs Join p1 In
(From p In DB.PROB_GROUPs Group By p.PGR_NAME, p.PGR_PCELL Into g = Group Select PGR_NAME, PGR_PCELL, H_VERSION = g.Max(Function(p) p.PGR_VERSION))
On p1.H_VERSION Equals pp.PGR_VERSION And p1.PGR_NAME Equals pp.PGR_NAME And p1.PGR_PCELL Equals pp.PGR_PCELL Select pp Order By pp.PGR_TYPE, pp.PGR_NAME
Should be ok right?