Predicate expression for inmemory filter with isnull

Posts   
 
    
mds avatar
mds
User
Posts: 33
Joined: 24-Sep-2006
# Posted on: 16-Jan-2011 20:02:20   

Hi, i'm using version 3.0 Final on a VB.NET 2010 project (selfservicing template)

I'm tring to obtain an EntityView (of xxxxx) from a collection using a predicate expression that behaves as the following sql clause

WHERE (CREDITO_INIZIALE IS NULL OR NUMERO_ACCESSI<CREDITO_INIZIALE)


Dim pr As New PredicateExpression
pr.add(AttivitaIscrittoFields.CreditoIniziale = System.DBNull.Value)
pr.AddWithOr((AttivitaIscrittoFields.CreditoIniziale <> System.DBNull.Value) _
           And (AttivitaIscrittoFields.NumeroAccessi < AttivitaIscrittoFields.CreditoIniziale))

Dim x as EntityView(of AttivitaIscrittoEntity)=_Iscritto.Attivita.CreateView(pr)

The target is to obtain all the element that have null in the [Credito Iniziale] field or, if that field is not null, that have the field [Numero Accessi] less than of it.

But if the related collection contains an entity that has the field [CreditoIniziale] to Nothing then the CreateView method generates an exception (ArgumentException: Object must be of type Int32)

The previous code is only a part of a much more complex expression, but the predicate expression above is sufficient to reproduce the issue...

Any idea on how to solve it ?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 17-Jan-2011 06:55:33   

Are you sure the exeption occurs in that code lines? What is the exception message and stack trace?

David Elizondo | LLBLGen Support Team
mds avatar
mds
User
Posts: 33
Joined: 24-Sep-2006
# Posted on: 17-Jan-2011 10:44:35   

Hi daelmo, thanks for response. My previous example code contains a mistake: in real code i use Add method of PredicateExpression instead of AddWithOr and this generates the error. Using AddWithOr solves it. But in a more complex code where more predicate expressions is combined it remains... look at this:


        Dim pr As New PredicateExpression
        pr.Add(AttivitaIscrittoFields.IsConclusa = False)

        Dim prCredit As New PredicateExpression
        prCredit.Add(AttivitaIscrittoFields.CreditoIniziale = System.DBNull.Value And AttivitaIscrittoFields.ScadenzaCredito = System.DBNull.Value)
        prCredit.AddWithOr((AttivitaIscrittoFields.CreditoIniziale <> System.DBNull.Value) And (AttivitaIscrittoFields.NumeroAccessi < AttivitaIscrittoFields.CreditoIniziale))
        prCredit.AddWithOr((AttivitaIscrittoFields.ScadenzaCredito <> System.DBNull.Value) And (AttivitaIscrittoFields.ScadenzaCredito >= Date.Today))
        pr.AddWithAnd(prCredit)
        Dim xx As EntityView(Of AttivitaIscrittoEntity) = _Iscritto.Attivita.CreateView(pr)

If _Iscritto.Attivita collection contains some entity with field [CreditoIniziale] equal Nothing (NULL in the DB) the following exception is generated when CreateView is called:


  System.ArgumentException occurred
  Message=Object must be of type Int32.
  Source=mscorlib
  StackTrace:
       at System.Int32.CompareTo(Object value)

And this is the detailed stack trace:


     mscorlib.dll!int.CompareTo(object value) + 0x88 bytes  
     mscorlib.dll!System.Collections.Comparer.Compare(object a, object b) + 0x5f bytes  
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. FieldCompareExpressionPredicate.InterpretPredicate(SD.LLBLGen.Pro.ORMSupportClasses. IEntityCore entity = {DAL.EntityClasses.AttivitaIscrittoEntity}) Line 335 + 0x10 bytes   C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. Predicate.SD.LLBLGen.Pro.ORMSupportClasses.IPredicateInterpret.Interpret( SD.LLBLGen.Pro.ORMSupportClasses.IEntityCore entity = {DAL.EntityClasses.AttivitaIscrittoEntity}) Line 165 + 0xe bytes  C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. PredicateExpression.InterpretPredicate(SD.LLBLGen.Pro.ORMSupportClasses. IEntityCore entity = {DAL.EntityClasses.AttivitaIscrittoEntity}) Line 323 + 0x12 bytes   C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. Predicate.SD.LLBLGen.Pro.ORMSupportClasses.IPredicateInterpret.Interpret( SD.LLBLGen.Pro.ORMSupportClasses.IEntityCore entity = {DAL.EntityClasses.AttivitaIscrittoEntity}) Line 165 + 0xe bytes  C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. PredicateExpression.InterpretPredicate(SD.LLBLGen.Pro.ORMSupportClasses.IEntityCore entity = {DAL.EntityClasses.AttivitaIscrittoEntity}) Line 323 + 0x12 bytes    C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. Predicate.SD.LLBLGen.Pro.ORMSupportClasses.IPredicateInterpret.Interpret( SD.LLBLGen.Pro.ORMSupportClasses.IEntityCore entity = {DAL.EntityClasses.AttivitaIscrittoEntity}) Line 165 + 0xe bytes  C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. PredicateExpression.InterpretPredicate(SD.LLBLGen.Pro.ORMSupportClasses.IEntityCore entity = {DAL.EntityClasses.AttivitaIscrittoEntity}) Line 323 + 0x12 bytes    C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. Predicate.SD.LLBLGen.Pro.ORMSupportClasses.IPredicateInterpret.Interpret (SD.LLBLGen.Pro.ORMSupportClasses.IEntityCore entity = {DAL.EntityClasses.AttivitaIscrittoEntity}) Line 165 + 0xe bytes  C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. CollectionCore<DAL.EntityClasses.AttivitaIscrittoEntity>.FindMatches( SD.LLBLGen.Pro.ORMSupportClasses.IPredicate filter = {SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression}) Line 557 + 0x21 bytes  C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. EntityViewBase<DAL.EntityClasses.AttivitaIscrittoEntity>.SetFilter(SD.LLBLGen.Pro.ORMSupportClasses.IPredicate filter = {SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression}) Line 307 + 0x17 bytes C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. EntityViewBase<DAL.EntityClasses.AttivitaIscrittoEntity>.InitClassCore( SD.LLBLGen.Pro.ORMSupportClasses.CollectionCore< DAL.EntityClasses.AttivitaIscrittoEntity> relatedCollection = {DAL.CollectionClasses.AttivitaIscrittoCollection}, SD.LLBLGen.Pro.ORMSupportClasses.IPredicate filterToApply = {SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression}, SD.LLBLGen.Pro.ORMSupportClasses.ISortExpression sorterToApply = null, SD.LLBLGen.Pro.ORMSupportClasses.PostCollectionChangeAction dataChangeAction = ReapplyFilterAndSorter) Line 752 C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro.ORMSupportClasses. EntityView<DAL.EntityClasses.AttivitaIscrittoEntity>.EntityView( SD.LLBLGen.Pro.ORMSupportClasses.CollectionCore<DAL.EntityClasses.AttivitaIscrittoEntity> relatedCollection = {DAL.CollectionClasses.AttivitaIscrittoCollection}, SD.LLBLGen.Pro.ORMSupportClasses.IPredicate filter = {SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression}, SD.LLBLGen.Pro.ORMSupportClasses.ISortExpression sorter = null, SD.LLBLGen.Pro.ORMSupportClasses.PostCollectionChangeAction dataChangeAction = ReapplyFilterAndSorter) Line 116   C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro. ORMSupportClasses. EntityCollectionBase<DAL.EntityClasses.AttivitaIscrittoEntity>.CreateView( SD.LLBLGen.Pro.ORMSupportClasses.IPredicate filter = {SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression}, SD.LLBLGen.Pro.ORMSupportClasses.ISortExpression sorter = null, SD.LLBLGen.Pro.ORMSupportClasses.PostCollectionChangeAction dataChangeAction = ReapplyFilterAndSorter) Line 406 + 0x4d bytes C#
     SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll!SD.LLBLGen.Pro. ORMSupportClasses. EntityCollectionBase<DAL.EntityClasses.AttivitaIscrittoEntity>.CreateView( SD.LLBLGen.Pro.ORMSupportClasses.IPredicate filter = {SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression}) Line 380 + 0x10 bytes    C#
>   CSManager.exe!CSManager.ucNotifiche.LoadAttivita() Line 55 + 0x2a bytes Basic

For the moment i solved it using a secondary collection that i fill after scan the first collection, element by element, and applying my condition...

Thanks for help.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 17-Jan-2011 15:20:55   

The original post had the following:

WHERE (CREDITO_INIZIALE IS NULL OR NUMERO_ACCESSI<CREDITO_INIZIALE)

Dim pr As New PredicateExpression pr.add(AttivitaIscrittoFields.CreditoIniziale = System.DBNull.Value) pr.AddWithOr((AttivitaIscrittoFields.CreditoIniziale <> System.DBNull.Value) _ And (AttivitaIscrittoFields.NumeroAccessi < AttivitaIscrittoFields.CreditoIniziale))

Dim x as EntityView(of AttivitaIscrittoEntity)=_Iscritto.Attivita.CreateView(pr)

For the above sql code I think the following filter is enough:

Dim pr As New PredicateExpression
pr.add(AttivitaIscrittoFields.CreditoIniziale = System.DBNull.Value)
pr.AddWithOr(AttivitaIscrittoFields.NumeroAccessi < AttivitaIscrittoFields.CreditoIniziale)

Anyway, I can't reproduce it with the following code:

            var orders = new EntityCollection<OrderEntity>();
            using(var adapter = new DataAccessAdapter())
            {               
                adapter.FetchEntityCollection(orders, null);
            }

            var filter = new PredicateExpression(OrderFields.ShipPostalCode == DBNull.Value);
            filter.AddWithOr(OrderFields.ShipPostalCode == "T2F 8M4");

            var ordersView = new EntityView2<OrderEntity>(orders, filter);

What am I doing wrong or differently? I don't think comparing to a value rather than a field should make any difference in this case.

mds avatar
mds
User
Posts: 33
Joined: 24-Sep-2006
# Posted on: 17-Jan-2011 16:37:44   

Hi Walaa, the simplified version of the expression don't have problem and yes, in this case it's unecessary retest again the null value ...

The exception is generated when i try to create a more complex expression (see my second message) corresponding to the following sql query ...


...WHERE (IS_CONCLUSA=0) 
AND 
(
   (CREDITO_INIZIALE IS NULL AND SCADENZA_CREDITO IS NULL)
   OR
   (CREDITO_INIZIALE IS NOT NULL AND NUMERO_ACCESSI<CREDITO_INIZIALE)
   OR
   (DATA_SCADENZA IS NOT NULL AND DATA_SCADENZA>=GETDATE())
)

Thanks.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 18-Jan-2011 06:08:44   

Is there any chance you can reproduce that on Norhtwind DB, or produce a tiny repro solution so we can identify your behavior?

David Elizondo | LLBLGen Support Team
mds avatar
mds
User
Posts: 33
Joined: 24-Sep-2006
# Posted on: 19-Jan-2011 00:09:31   

Hi daelmo It 's a bad time to do it now cry As soon as I get time I will ... Thanks and see you soon