Path Expected for Join! Nhibernate Error - nhibernate

I trying to do a join and I keep getting this error
Path expected for join! [SELECT
t.CourseId FROM Task as t INNER JOIN
Courses as c, CoursePermissions as cp
WHERE (t.CourseId = 1)]
I have
const string query = "SELECT t.CourseId FROM Task as t INNER JOIN Courses as c, CoursePermissions as cp WHERE (t.CourseId = 1)";
var a = session.CreateQuery(query);
My Sql I am trying to achieve
SELECT dbo.Tasks.CourseId
FROM dbo.Tasks INNER JOIN
dbo.Courses ON dbo.Tasks.CourseId = dbo.Courses.CourseId INNER JOIN
dbo.CoursePermissions ON dbo.Courses.CourseId = dbo.CoursePermissions.CourseId
WHERE (dbo.Tasks.CourseId = 1)
I am using nhibernate 3.1 and fluent nhibernate 1.2

It means that you using an inner join in HQL works a little different than using it in SQL. In HQL you join the tables by providing the "path", which is basically the referenced property of your class.
So instead of
SELECT t.CourseId FROM Task as t INNER JOIN Courses as c ...
you need to write
// c.Taks is the IList property in your Courses class
SELECT t.CourseId FROM Courses as c INNER JOIN c.Tasks as t ...

Although Florian Lim has suggested a great solution but in my case I didn't had IList for Tasks in Courses. I achieved that through Theta-Style Joins which actually is Cartesian product provide all possible combinations which can be filtered (in where clause) according to need.

Related

Entity Framework with Multiple Joins and Subquery

I have a complex query with multiple left joins and subqueries which I need to implement in Entify Framework. I've received the monster SQL and
my goal is to do it on a elegant way with EF. The query consumes multiple tables and creates a "WITH" subquery on top which
is included in the joins later. I've done a first approach with EF but when I inspect the output that EF sends to the DB, inner joins are sent when
I am expecting LEFT JOINs.
A summary of the SQL follows:
WITH SUB_QUERY
AS ( SELECT FIELD_A,
FIELD_B,
FIELD_C,
MAX (FIELD_D) MAX_FIELD_D
FROM TABLE_X
WHERE SOME FIELD_A = 'WHATEVER'
GROUP BY FIELD_A, FIELD_B, FIELD_C)
SELECT C.FIELD_A,
C.FIELD_B,
B.FIELD_X,
D.FIELD_S,
E.FIELD_J,
F.FIELD_Y
FROM TABLE_A A
LEFT JOIN SUB_QUERY B
ON A.FIELD_C = B.FIELD_C
LEFT JOIN TABLE_C C
ON B.FIELD_A = C.FIELD_A
LEFT JOIN TABLE_D D
ON A.FIELD_C = D.FIELD_C
LEFT JOIN TABLE_E E
ON A.FIELD_X = E.FIELD_X
LEFT JOIN TABLE_F F
ON A.FIELD_W = F.FIELD_W
WHERE A.FIELD_H = D.FIELD_H
AND A.FIELD_D = B.MAX_FIELD_D
As you see, a subquery on top filters and groups some data to be consumed in a join below. Then all the joins take place
and some fields are taken from different tables as the output of the query.
Which approach would you recommend me to accomplish this task? I've tried different approaches and no one of them works (either retrieve nothing, or many more rows than the SQL query on the DB, etc..)
Please note that the Domain Model in Entity Framework is properly setup: Primary Keys, collections, nested objects etc.. so I believe some of these
joins are not even required because my EF entities contain already references to the child collections and parent objects (navigation properties).
Thanks a lot!!
if you really need a left join you should mode the where condition related to a left joined table in the proper on clause
FROM TABLE_A A
LEFT JOIN SUB_QUERY B
ON A.FIELD_C = B.FIELD_C
LEFT JOIN TABLE_C C
ON B.FIELD_A = C.FIELD_A
LEFT JOIN TABLE_D D
ON A.FIELD_C = D.FIELD_C AND A.FIELD_D = B.MAX_FIELD_D
LEFT JOIN TABLE_E E
ON A.FIELD_X = E.FIELD_X
LEFT JOIN TABLE_F F
ON A.FIELD_W = F.FIELD_W
the use of a left join table column in where force the relation to work as a INNER JOIN

I need help formatting inner join command in SQL query

Here is my ERD for SQL Server:
https://c2.staticflickr.com/6/5832/23786188186_d6f1d93132_o.jpg
I need to find out which books are associated with each publisher.
USE BookStoreDB
SELECT ProductID
FROM Books
INNER JOIN [Publishers] PublisherID ON PublishersID = ProductID
I'm assuming I just didn't create the INNER JOIN command correctly?
SELECT p.PublisherID, b.ProductID
FROM Books b
INNER JOIN Publishers p ON p.PublisherID = b.PublisherID
The ON part of a join defines how the two tables are related to each other. In your case, it would be:
INNER JOIN Publishers ON (Books.PublisherID = Publishers.PublisherID)
If you put something between the name of the table, and the ON, it's treated as an alias. You can (and should) also use these aliases in your SELECT
FROM Books B
INNER JOIN Publishers P ON (B.PublisherID = P.PublisherID)
Finally, you probably want to select information that will actually tell you who the publisher is:
SELECT B.ISBN, P.CompanyName
FROM Books B
INNER JOIN Publishers P ON (B.PublisherID = P.PublisherID)

Postgres SQL inner join syntax

Can some one please explain the inner join syntax in the SQL below:
CREATE TABLE dataset AS
SELECT property.id
, amount.band
, amount."value"
FROM property
INNER JOIN (locality INNER JOIN amount ON locality.code = amount.code) ON (property.band = amount.band) AND (property.id = locality."UniqueId")
Why is the table locality defined before the second inner join? I've never come across such strange syntax.
Is there a more clearer way to right the same query so that someone can easily understand whats going on?
FROM property
INNER JOIN (locality INNER JOIN amount ON locality.code = amount.code)
ON (property.band = amount.band) AND (property.id = amount."UniqueId")
is the same as
FROM property
INNER JOIN amount ON property.band = amount.band AND property.id = amount."UniqueId"
INNER JOIN locality ON locality.code = amount.code
When INNER JOINs only, you can re-order them as you want.
(Any specific reason to JOIN locality? You don't select any of its columns. Is it some kind of EXISTS, or do you want multiple rows returned if there are several matching rows in that table?)

How to make SQL query inner join when tables are connected by a bridge table?

I have create many to many relationships using code first entity framework.
Here the tables generated in DB:
I want to make sql query inner join Students on the Courses,but I don't know how to implement it in this case when bridge table between them.
How can I make sql query inner join Students on the Courses?
Try this
Select c.CourseId,c.CourseName,sc.StudentId,s.StudentName
from Courses c Inner Join StudentCourses sc On c.CourseId = sc.Course_CourseId
Inner Join Student s ON sc.Student_StudentId = s.StudentId

struggling with a left join in a nHibernate query

I'm struggling to replicate a simple sql left join in a nHibernate query. Other answers on SO have led me to be more confused as to what is the smartest way to tackle left joins in a domain query.
Example:
2 DB Tables:
Customer
CustId INT PK
Orders
OrderId INT PK
CustId INT FK
Status INT
1 SQL Query:
Select c.CustId from Customer c
left join Orders o on o.CustId = c.CustId and o.Status = 2
where o.OrderId is null
This will retrieve a unique list of Customers who don't have an order in status 2,
Note, it also includes customers who don't have an order at all.
This is a contrived example to simplify this question, but this type of query is very useful and not easy to do any other way.
Imagine nh mappings for "Customer" and "Orders" which simply reflect the example tables above.
Is there a simple way to extract my list of unique, non-status-2 customers in nHibernate, in a query, without resorting to a SQL query or ending up in a select n+1 scenario?
Query preferences:
1 linq-to-nhibernate
2 QueryOver
3 HQL
4 Criteria.
Thanks.
See http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/queryhql.html#queryhql-joins. It's the Hibernate reference, and not the nHibernate reference, but I'd assume they work the same (BTW, this post seems to confirm it):
You may supply extra join conditions using the HQL with keyword.
from Cat as cat
left join cat.kittens as kitten
with kitten.bodyWeight > 10.0
So, in your case, it should look like
select c.CustId from Customer c
left join Orders o with o.Status = 2
NHibernate 3.0 has an overload method for ICriteria .CreateAlias which takes 4 params, the last param is withClause.
Here is an example:
DetachedCriteria criteria = DetachedCriteria.For<Models.BO.Customer>("customer")
.CreateAlias(ReflectionHelper.PropertyName<Models.BO.Customer>(x => ((Models.BO.Interfaces.ICustomerQueryOnly) x).Tasks),
"activeTasks", JoinType.LeftOuterJoin, Restrictions.IsNotNull("activeTasks.LockedBy")
)
.CreateAlias(ReflectionHelper.PropertyName<Models.BO.Customer>(x => ((Models.BO.Interfaces.ICustomerQueryOnly) x).Tasks2),
"availableTasks", JoinType.LeftOuterJoin,
availableTasksRestraction
)
.Add(Restrictions.Eq("CustomerBase", _customerBase))
.Add(Restrictions.Eq("IsActive", true));
which endup with something like:
FROM Customers c
left join Tasks t on t.customerId = c.Id and (t.DeletedDate is null and
t.lockedById is null and [etc])
left join Tasks activetasks [etc]
where [...]
In this example I need to extract all customers and number of available tasks and number of active task for each customer.
If the entities are unrelated and you don't wish to map a relation, you can use a theta join. See here
Maybe something like
Select c from Customer c, Order o
where o.CustId = c.CustId and o.Status = 2