FetchPredicateExpressionToUse

Posts   
 
    
jshallard
User
Posts: 62
Joined: 23-Mar-2005
# Posted on: 07-Sep-2005 16:25:00   

This is not a bug, it is a feature request sunglasses

It would be really nice if there was a way to set a PredicateExpression for an Entity and an EntityCollection that would automatically be used in "Get" & "GetMulti" methods. It could work in much the same way as the ConcurrencyPredicateFactoryToUse and _ EntityValidatorToUse_.

This feature, combined with the TDL "EntityFieldExist" tag, (http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=4049) would provide really powerful tools to allow organizations with strong database naming conventions to create allot of predicate code automatically.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 08-Sep-2005 11:04:23   

jshallard wrote:

This is not a bug, it is a feature request sunglasses

It would be really nice if there was a way to set a PredicateExpression for an Entity and an EntityCollection that would automatically be used in "Get" & "GetMulti" methods. It could work in much the same way as the ConcurrencyPredicateFactoryToUse and _ EntityValidatorToUse_.

This feature, combined with the TDL "EntityFieldExist" tag, (http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=4049) would provide really powerful tools to allow organizations with strong database naming conventions to create allot of predicate code automatically.

Do you mean, a filter which is used when you do myCustomer.Orders, which calls GetMultiOrders() ?

Frans Bouma | Lead developer LLBLGen Pro
jshallard
User
Posts: 62
Joined: 23-Mar-2005
# Posted on: 08-Sep-2005 12:33:11   

Yes - basically that Idea. I am currently using the the SelfServicing templates ('Two class scenario') and achieving a similar thing by overriding the Collection Properties from the EntityBase.

However, if there was a "ConcurrencyPredicateFactoryToUse" type of setup, it would allow for the setting or overriding of this behaviour on the fly. Perhaps each relation could have its own predicateExpression property, and if it was not null, it would be used as a filter on the Collection retrieval. This way, it would be possible to set up the entity to initialise with default filter behaviours. Maybe the Property could be something like the following:


public virtual CollectionClasses.OrdersCollection Orders
{
    get
    {
        CollectionClasses.OrdersCollection OrdersCollection = null;
                
        //get collection
        if(this.FetchOrderPredicateExpressionToUse != null)
        {
            OrdersCollection = GetMultiOrders(false, this.FetchOrderPredicateExpressionToUse);
        }
        else
        {
            OrdersCollection = GetMultiOrders(false);
        }

        return OrdersCollection;
    }
}

If this was combined with an TDL "EntityFieldExist" tag, it would be possible to write code in the include templates that would automatically register filter predicates when certain fields exist (such as "Deleted"). It could be CodeGen heaven!

If may also be useful if this could be extended to the EntityInstantiation. Perhaps a property on each Entity "FetchPredicateExpressionToUse" could automatically apply a filter on the instantiation. EG:

/// <summary> /// CTor /// </summary> /// <param name="pkId">PK value for Orders which data should be fetched into this Orders object</param> public OrdersEntityBase(System.Int64 pkId) { if(this.FetchPredicateExpressionToUse != null) { InitClassFetch(pkId, new OrdersValidator(), new PropertyDescriptorFactory(), new OrdersEntityFactory(), null, this.FetchPredicateExpressionToUse); } else { InitClassFetch(pkId, new OrdersValidator(), new PropertyDescriptorFactory(), new OrdersEntityFactory(), null); } }

Here is a quick example of where i see this as being useful, so you can see where i am coming from:

When items (such as orders) are "deleted", they are often needed for future reporting purposes, as so are not really deleted, but a "Deleted" field is marked as true in the database. One of the problems I have found with this is that allot of extra filter code is required, and that developers (including myself) are prone to forget to filter out the deleted items. With features such as the above suggested, it would be possible to set up the entities so that by default they would not return any item where the deleted field was true. This would be a great time saver, and also make for more consistent and robust software.

You may know of many good reasons why all of the above is either not practical or sensible - in which case ignore this!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 09-Sep-2005 11:27:06   

In case of the Deleted flag aspect, I follow you and in that situation it's useful. On other occasions I'm not that sure, simply because customer.Orders is the set of all orders, or if you want a subset, call customer.GetMultiOrders(true, filter)

You can of course add this property with an include template in the derived entity: override the properties there, and use the code as you proposed above, and also create the property / private variable for the filter. Would that solve your problem?

In 1.0.2005.1 you'll be able to use .lpt templates (which can access the complete object graph using normal C# / VB.NET code) as include templates, so it will become even easier then.

Frans Bouma | Lead developer LLBLGen Pro
jshallard
User
Posts: 62
Joined: 23-Mar-2005
# Posted on: 12-Sep-2005 21:28:17   

Yes, overriding does solve my problem - an in fact that is what i have been doing. The template sets a very flexible, and allow me to do many things like that - for which i am always grateful. sunglasses

I see your point that "customer.Orders" (for example) should always be the set of all orders. however - my argument is that is should not have to be. I would say that in most real life scenarios, people do not want every single order in the system. They would probably want, for example, all the outstanding orders most of the time instead.

The ability for coders to add default predicates to a class is perhaps _ more_ powerful, as it allows for the setting up of an entity as it will be used the most. Then, in the less frequent situations where all orders do want to be retreived, this behavour can be overridden.

Just my two cents worth wink

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 14-Sep-2005 11:20:14   

jshallard wrote:

Yes, overriding does solve my problem - an in fact that is what i have been doing. The template sets a very flexible, and allow me to do many things like that - for which i am always grateful. sunglasses

I see your point that "customer.Orders" (for example) should always be the set of all orders. however - my argument is that is should not have to be. I would say that in most real life scenarios, people do not want every single order in the system. They would probably want, for example, all the outstanding orders most of the time instead.

The ability for coders to add default predicates to a class is perhaps _ more_ powerful, as it allows for the setting up of an entity as it will be used the most. Then, in the less frequent situations where all orders do want to be retreived, this behavour can be overridden. Just my two cents worth wink

If you want a subset, you should use the OrderCollection, and setup a filter, at least that's what I think should be done. Or call GetMultiOrders(..., filter, ....) The property customer.Orders is mainly to navigate the graph, using lazy loading. Adding a filter somewhere, changes the semantical meaning of customer.Orders IMHO.

Frans Bouma | Lead developer LLBLGen Pro