Join Table to Itself & Filter

Posts   
 
    
Posts: 3
Joined: 09-Dec-2015
# Posted on: 09-Dec-2015 18:03:14   

I've got a table, Management, which has a ParentID column, that joins to ManagementID. This works fine, but when I filter on a text value in the parent, it's actually using the children. This was working fine, until we upgraded from 3.1 to 4.2, recently.

LLBLGen Pro 4.2 Template group: Adapter, with Deprecated TwoClasses preset .NET 4.5.1 SQL Server 2014

The generated query looks like this (extra columns and joins removed for brevity, I'm happy to send in full, if that helps):

SELECT DISTINCT TOP(50) [dbo].[Management].[ManagementID], [dbo].[Management].[ManagementName], 
[LPA_P1].[ManagementName] AS [ParentManagementName], [dbo].[Management].[ParentID], [dbo].[Management].[RootID]
FROM ( [dbo].[Management] [LPA_P1]  
RIGHT JOIN [dbo].[Management]  ON  [LPA_P1].[ManagementID]=[dbo].[Management].[ParentID]) 
WHERE ( [dbo].[Management].[Deleted] <> 1 
AND ( ( [dbo].[Management].[ManagementName] LIKE '%region%')))
ORDER BY [dbo].[Management].[ManagementName] ASC

The ManagementName in the Where clause should actually be against the aliased table, like this:

SELECT DISTINCT TOP(50) [dbo].[Management].[ManagementID], [dbo].[Management].[ManagementName], 
[LPA_P1].[ManagementName] AS [ParentManagementName], [dbo].[Management].[ParentID], [dbo].[Management].[RootID]
FROM ( [dbo].[Management] [LPA_P1]  
RIGHT JOIN [dbo].[Management]  ON  [LPA_P1].[ManagementID]=[dbo].[Management].[ParentID]) 
WHERE ( [dbo].[Management].[Deleted] <> 1 
AND ( ( [LPA_P1].[ManagementName] LIKE '%region%')))
ORDER BY [dbo].[Management].[ManagementName] ASC

The code where this is set up looks like this (again, extra stuff removed for brevity):

public DataTable GetManagementDynamicListForGrid(int? levelID, int languageKey, string loggedInUserID, FilterArguments fArgs, out int virtualItemCount)
{
    IPredicateExpression customFilter;
    IEntityRelation relation;

    ResultsetFields fields = new ResultsetFields(25);
    fields.DefineField(ManagementFields.ManagementID, 0, "ManagementID", "", AggregateFunction.None);
    fields.DefineField(ManagementFields.ManagementName, 1, "ManagementName", "", AggregateFunction.None);
    fields.DefineField(ManagementFields.ManagementName, 4, "ParentManagementName", "Parent", AggregateFunction.None);
    fields.DefineField(ManagementFields.ParentID, 5, "ParentID", "", AggregateFunction.None);
    fields.DefineField(ManagementFields.RootID, 6, "RootID", "", AggregateFunction.None);
    
    IRelationPredicateBucket bucket = new RelationPredicateBucket();

    bucket.Relations.Add(ManagementEntity.Relations.ManagementEntityUsingParentID, "Parent", "", JoinHint.Right);
    customFilter = new PredicateExpression();
    relation.CustomFilter = customFilter;
    
    bucket.PredicateExpression.AddWithAnd(ManagementFields.Deleted != true);

    if (fArgs != null)
    {
        fArgs.AddPredicateToBucket(bucket);
    }

    ISortExpression sortExpression = null;
    if (fArgs != null)
    {
        sortExpression = fArgs.SortExpression;
    }
    if (sortExpression == null)
    {
        sortExpression = new SortExpression(ManagementFields.ManagementName | SortOperator.Ascending);
    }

    DataTable dynamicList = new DataTable();

    using (DataAdapter adapter = new DataAdapter(true))
    {
        virtualItemCount = adapter.GetDbCount(fields, bucket, null, false);
        if (fArgs != null)
            adapter.FetchTypedList(fields, dynamicList, bucket, 0, sortExpression, false, null, fArgs.PageNumber, fArgs.PageSize);
        else
            adapter.FetchTypedList(fields, dynamicList, bucket, 0, sortExpression, false, null);
    }

    return dynamicList;
}

So, again, the filter should be on the Parent ManagementName column, so that if I filter by the parent name of "region", it returns the children that have a parent with "region" in the ManagementName. Instead, it's giving me results where "region" is in the ManagementName of the child records.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 10-Dec-2015 08:57:15   

This line actually looks like reverse:

 bucket.Relations.Add(ManagementEntity.Relations.ManagementEntityUsingParentID, "Parent", "", JoinHint.Right);

As the second parameter is the start entity in the relation, the third one is the end side entity. As you are using ManagementEntity.Relations.ManagementEntityUsingParentID it looks like the end entity is actually the parent.

Also you missed an important part in your posted code: the construction of the customFilter and the construction of the filter of the ManagementName filter.

David Elizondo | LLBLGen Support Team