Define join condition in code - nhibernate

Is it possible to code (not mapping) following query CONDITION for NHibernate join criteria for lazy child list?
...
JOIN ChildTable child ON child.ParentID = parent.ID AND <CONDITION>
NHibernate 2.1

Yes it's possible to write that query using the criterion or the QueryOver API. Here's an example with QueryOver api
Child childAlias = null;
session.QueryOver<Parent>()
.JoinAlias(w => w.Children,
() => childAlias ,
JoinType.None,
Restrictions.Where<Child>(s => s.Active)
).List();

Related

JPA 2.1 Left join on sub collection with filter of sub collection via 'on' clause

Given the following JPQL query:
Select p, child, subChild
from Entity parent p
left join Child parent.children child
left join SubChid child.subChildren subChild on subChild.field = 'value'
I expect to have the parent entity with only child which have subChild with field = 'value' and I also expect to have the child.subChildren filtered to only return the one matching the 'on' clause. I am wondering if this is allowed by JPA 2.1. This seems to be but I tried with eclipselink 2.5.3 and it doesn't work as expected.
The SQL query generated is correct. It returns only the expected rows but the parent entity is not filtered and is returned with the complete object graph which I don't understand.
Can someone give me some inside on how to solve that issue?

How to transform mysql query into Yii CDbCriteria object?

I have a model Reporter.
public function relations() {
return array(
'video' => array(self::HAS_MANY, 'Video', 'reporter_id'),
);
}
I have a mysql query for Reporter->search() method:
SELECT t.*, COUNT(t1.id) AS 'reports'
FROM reporter AS t
LEFT JOIN video AS t1 ON t.id = t1.reporter_id
GROUP BY t.id
ORDER BY t.name
How can it be written in terms of CDbCriteria to use with CActiveDataProvider?
To write that query into the criteria for a CActiveDataProvider you'll need to set the following properties from CDbCriteria:
select,
join,
group, and
order.
You can then set them while creating a new CActiveDataProvider object like so:
$dataProvider=new CActiveDataProvider('Reporter', array(
'criteria'=>array(
'select'=>'`t`.*, count(`t1`.`id`) as `reports`',
'join'=>'LEFT JOIN `video` AS `t1` ON `t`.`id` = `t1`.`reporter_id`',
'group'=>'`t`.`id`',
'order'=>'`t`.`name`',
),
));
The whole list of properties and methods that you can use with CDbCriteria can be found here: CDbCriteria Class Reference

Linq to NHibernate generating multiple joins to the same table

When I have a reference to the same table in my select as in my where clause, linq to Nhibernate generates two joins, one for the select and one for the where. i.e.
from child in Session.Query<Child>()
where child.Parent.Name == "Bob"
select new Info
{
ParentAge = child.Parent.Age,
ChildName = child.Name
};
Generates SQL like:
Select this_.Name,
parent1.Age
From Child this_
left join Parent parent1 on child.ParentId = parent1.Id,
Parent parent2
Where child.ParentId = parent2.Id and parent2.Name = 'Bob'
I would have thought I should get SQL more like:
Select this_.Name,
parent1.Age
From Child this_
inner join Parent parent1 on child.ParentId = parent1.Id
Where parent1.Name = 'Bob'
Is there a way to structure the query to get this?
Does it matter?
You can prevent NHibernate from doing this by using a transparent identifier, so that your query looks like this:
from child in Session.Query<Child>()
let p = child.Parent
where p.Name == "Bob"
select new Info {
ParentAge = p.Age,
ChildName = child.Name
};
Have you tried comparing the query execution plan for each in SSMS? If the duplicated join is eliminated in SQL Server, then it doesn't matter. I've found that to be the case in a few instances where I thought the generated query was going to be very inefficient, but after optimization it ends up exactly the same as a query that looks much better.

Linq2NHibernate - Only Left Joins?

Really quick question..
Does Linq2NHibernate always create a left join to retrieve relationships? Is there a way that I can get an inner one instead?
Thank you in advance.
Filipe
As far as I know.
For any relationship that is not One-to-One, NHibernate makes the assumption that the relationship could have 0 to many results, thus uses a Left Join.
I don't know about Linq2NHibernate, but in NH3 using QueryOver API you can specify the join types.
For example, give a Product with a Category. If you wrote:
var result = Session.QueryOver<Product>()
.Fetch(x => x.Category).Eager
.List();
This will result in a left join, if you wanted to specify an inner join you could write the same query as:
var result = Session.QueryOver<Product>()
.JoinQueryOver(x => x.Category, JoinType.InnerJoin)
.List();
This will result in an Inner Join.
As far as I know you can't specify join types when using the LINQ provider (Query<T> in NH3)

Left Join on Many-to-One Mapping

I have a reference to call that may or may not be there. When I add the nullable option it still doing Inner Join when I want an Left Join (show the left even if the right is null). Is this possible in the NH map?
References(x => x.DefaultCategory, "CATEGORY_ID")
.Nullable();
The join type isn't specified in the mapping, but in the query.
IN HQL, use left join syntax as with SQL.
With Criteria, use:
.CreateAlias("categories", "c", JoinType.LeftOuterJoin)