DynamicRelation and CustomFilter

Posts   
 
    
cerberis
User
Posts: 92
Joined: 20-May-2011
# Posted on: 14-Jul-2014 13:59:13   

Hello,

is there any way to add custom filter for IDynamicRelation object? The point is that I have generic code (at adapter level) where I put some filters for all my selects which are needed for scoping reasons. Recently I noticed that queries written with Query factory generates dynamic relations instead of entity relations and I was not able to find the way to add custom filter to these relations.

I know that I can add additional filter to where clause, however I would like to avoid additional check for Null when doing left join.

Any ideas, how it can be done? LLBLGen 4.2, Adapter scenarion, .NET 4.5.1

regards Mantas

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 14-Jul-2014 18:13:04   

DynamicRelation requires you to specify a custom ON clause predicate. The custom filter has to be added there.

Check the DynamicRelation CTor overloads.

cerberis
User
Posts: 92
Joined: 20-May-2011
# Posted on: 15-Jul-2014 12:07:24   

Walaa wrote:

DynamicRelation requires you to specify a custom ON clause predicate. The custom filter has to be added there.

Check the DynamicRelation CTor overloads.

Maybe any suggestions how to do this? I have this method in adapter: protected override IRetrievalQuery CreateSelectDQ(QueryParameters parameters)

inside it I analyse what tables are involved and add additional filters like:

foreach (var relationToUse in parameters.RelationsToUse) { if (relationToUse is IEntityRelation) { var relation = relationToUse as IEntityRelation; var fields = relation.GetAllFKEntityFieldCoreObjects(); relation.CustomFilter = CreateScopeFilter(fields); } else if (relationToUse is IDynamicRelation) { // code here? } }

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 16-Jul-2014 00:47:24   

I think the same question was asked here: https://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=22810 Does the above thread answer your question?

cerberis
User
Posts: 92
Joined: 20-May-2011
# Posted on: 16-Jul-2014 11:41:40   

Walaa wrote:

I think the same question was asked here: https://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=22810 Does the above thread answer your question?

Partly. I know the way to change where clause. However that means I need to do additional check for null if I have left join. But that's fine I guess simple_smile

cerberis
User
Posts: 92
Joined: 20-May-2011
# Posted on: 16-Jun-2015 11:02:26   

Hello,

seems that I still run into some troubles when using where clause instead of filter in join. So still searching for a way to extend filter (OnClause) in dynamic relation. I have such code:



var relation = queryParameters.RelationsToUse[i] as IDynamicRelation;
if (relation.OnClause != null)
{
     relation = new CustomDynamicRelation(
                inheritanceInfoProvider, 
                relation.JoinType,
                relation.AliasLeftOperand, relation.AliasRightOperand,
                relation.OnClause,
                relation.LeftOperand,
                relation.RightOperand);

    queryParameters.RelationsToUse[i] = relation
}

and I have such class


private class CustomDynamicRelation : DynamicRelationBase
{
    private readonly IInheritanceInfoProvider _inheritanceInfoProvider;

    public CustomDynamicRelation(IInheritanceInfoProvider inheritanceInfoProvider, JoinHint joinType, string aliasLeftOperand, string aliasRightOperand, IPredicate onClause, object leftOperand, object rightOperand)
    {
        _inheritanceInfoProvider = inheritanceInfoProvider;
        InitClass(joinType, aliasLeftOperand, aliasRightOperand, onClause, leftOperand, rightOperand);
    }

    protected override IInheritanceInfoProvider GetInheritanceProvider()
    {
        return _inheritanceInfoProvider;
    }
}

However - I get an error: SD.LLBLGen.Pro.ORMSupportClasses.ORMRelationException: Relation at index 4 doesn't contain an entity already added to the FROM clause. Bad alias?

So my question - what I am doing wrong. Basically I just recreated same dynamic relation (next step to change OnClause), using same fields, but seems that LLBL does not like this.

Any ideas?

Version (using adapter scenario):

SD.LLBLGen.Pro.DQE.SqlServer.4.2.20150323 SD.LLBLGen.Pro.ORMSupportClasses.4.2.20150323

regards Mantas

cerberis
User
Posts: 92
Joined: 20-May-2011
# Posted on: 16-Jun-2015 13:14:25   

Seems like I was able to track down the problem. I am inserting additional filter in overridden adapter methods like CreateSelectDQ, CreateRowCountDQ. When QueryParameters comes to this, it already has filled PersistenceInfo properties. So I managed to fill these properties and now it works.

However - the way of doing this not very convenient. I guess if adapter would have PrepareParametersForCollectionFetch method not private, but protected - would be much more easier simple_smile

Thank you for reading this simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 17-Jun-2015 10:18:29   

Are these extra filters always at the top level or also in inner queries? E.g. when a query is used as a derived table inside a join in a scalar query somewhere deep in the where clause, do you need to add the extra filters there too? I want to avoid making things protected when they should stay private. Though it's also not our goal to have customers do excessive work and add complex code to work around a limitation which perhaps breaks in future versions causing problems along the way.

Frans Bouma | Lead developer LLBLGen Pro
cerberis
User
Posts: 92
Joined: 20-May-2011
# Posted on: 17-Jun-2015 15:15:25   

We need to add these filters to any query which has specific columns. So basically it can be top query, query generated by prefetch path, subquery, etc..

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 19-Jun-2015 11:20:14   

Ok. It is possible to intercept before the query creation methods I think, with overriding e.g. FetchEntityCollection(QueryParameters). You can append the where clause in the override, and you don't have to add the persistence info yourself then.

This does require some more overrides than just the query construction method, but at the same time you can do query augmentation on an easier level. E.g. use the GraphTraverser classes (derived classes from QueryApiObjectTraverser, which is a visitor which can traverse elements recursively and collect info for you, like predicates), to analyze the query deeper than just the top elements.

Hope this helps simple_smile

Frans Bouma | Lead developer LLBLGen Pro
cerberis
User
Posts: 92
Joined: 20-May-2011
# Posted on: 19-Jun-2015 12:49:21   

Well.. that's true for parent query, but prefetch path uses FetchEntityCollectionInternal, which will not get additional filters in that case..

On the other hand, now I got an idea maybe to add additional filters to it. Will it work?

However - I would not want to override every public method. One reason - there are a lot of them. Another - new versions might introduce new ones which then will be unnoticed.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 20-Jun-2015 08:42:16   

cerberis wrote:

On the other hand, now I got an idea maybe to add additional filters to it. Will it work?

Sure, you can add additional filters to prefetchPaths.

David Elizondo | LLBLGen Support Team