- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Predicate expression for inmemory filter with isnull
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 ?
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.
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.
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.