0

I am trying to join aliases multiple times but it depends on the number of times it should do it.

Employee employeeAlias = null;
Thing thingAlias = null;
var names = string[] {"A", "B", "C", "D", "E"} // number of values could vary
for(int i = 0; i < names.Length ; i++)
{
   queryOver
       .JoinAlias(() => employeeAlias.Things, 
                  () => thingAlias,
                  JoinType.LeftOuterJoin, 
                  Restrictions.Eq(Projections.Property(() => thingAlias.Name, 
                                  names[i]));
}

However, upon execution, NHibernate throws an error saying:

NHibernate.QueryException: duplicate alias: thingAlias ---> System.ArgumentException: An item with the same key has already been added

Is there a way I can make NHibernate join an alias with a specified name so that it will not re-use the name of the variable?

Thanks guys. This has been my problem since yesterday and I can't find a proper solution.

PS:

I'm trying to do something like this:

SELECT * FROM Employee e
LEFT OUTER JOIN Thing t on e.Id = t.EmployeedId AND t.Name = "A"
LEFT OUTER JOIN Thing t on e.Id = t.EmployeedId AND t.Name = "B"
raberana
  • 11,739
  • 18
  • 69
  • 95

2 Answers2

1

What you are trying to achieve is impossible. Each relation (many-to-one, one-to-many) can be used exactly once.

To support this statement, please, check it here: CriteriaQueryTranslator.cs

private void CreateAssociationPathCriteriaMap()
{
    foreach (CriteriaImpl.Subcriteria crit in rootCriteria.IterateSubcriteria())
    {
        string wholeAssociationPath = GetWholeAssociationPath(crit);
        try
        {
            associationPathCriteriaMap.Add(wholeAssociationPath, crit);
        }
        catch (ArgumentException ae)
        {
            throw new QueryException("duplicate association path: "
                                    + wholeAssociationPath, ae);
        }

So, what we can see here, regardless of aliases, at the end, all associtated relations (JOINS) are added into associationPathCriteriaMap, which is IDictionary<string, ICriteria>.

That means, that there is now way how to have two same keys in play...

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • please take a look at my last edit.. do you have any idea on how i can do it in nhibernate? The reason I asked my question earlier is because I thought that way was the correct way of achieving my desired sql script. – raberana Nov 22 '14 at 09:21
  • I would say, the only, or **the** way is to map more collections to the same table. And you would need to use WHERE to filter them. I mean to have Things1, Things2, Things3 and then you can join them as required. Check http://nhforge.org/doc/nh/en/index.html#collections-mapping attribute `where` – Radim Köhler Nov 22 '14 at 10:13
  • but does it mean i will be hardcoding it? the number of joins is dynamic. cant hardcode things1, things2, things3.. :( – raberana Nov 22 '14 at 10:18
  • Exactly. But this is **the** solution with NHibernate. That's how it was designed. If you want to get something into query 1) relation must exist 2) can be used only once. BUT I would say, that **the question** is: why you need that? for filtering? then you should change the approach and use `I.` subqueries (you can have lot of them) and then filter the `II.` root query with their results... Maybe check this answer http://stackoverflow.com/a/23905744/1679310 where I show how to use Subqueries ... really heavily ;) – Radim Köhler Nov 22 '14 at 10:22
  • kind of. i want to check if the rows contains a certain value in the name colum. that is why i am using a left outer join for each of those values. – raberana Nov 22 '14 at 11:00
  • Subquery is the answer. Search how to, you will get functionality you need. I am sure... – Radim Köhler Nov 22 '14 at 11:19
0

I didn't tried this but I think instead of using for-loop and Restrictions.Eq, we can (not sure, but in case you didn't tried it) use Restrictions.In like-

Restrictions.In(Projections.Property(() => thingAlias.Name, names));
Pankaj Dubey
  • 796
  • 3
  • 8
  • 32