Value comparison expression

Posts   
 
    
Posts: 34
Joined: 20-Apr-2005
# Posted on: 01-Jun-2005 12:48:29   

I am using varbinaries to store extensible bitmasks and am damned if I can figure out how to create an appropriate expression.

I am trying to build up queries from sub expressions like:

(([Applicant].[PreferenceMask] & 1) != 0) AND (([Applicant].[LocationMask] & 8 ) != 0) OR ([Applicant].[PreferenceMask] & 1) = 0)

and

((([Applicant].[PreferenceMask] & 3) != 0) AND ([Applicant].[Bedrooms] > 1) AND [Applicant].[Bedrooms] < 6)) OR ([Applicant].[PreferenceMask] & 1) = 0)

Can I build expressions like this, or am I going to have to implement a sproc confused

Ryan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 01-Jun-2005 13:10:00   

You can use SqlServer's bit operators in an expression simple_smile . It's a bit more work, you first have to create an expression of field bitop value and then use that expression to compare it to a value.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 34
Joined: 20-Apr-2005
# Posted on: 01-Jun-2005 13:51:18   

Otis wrote:

You can use SqlServer's bit operators in an expression simple_smile . It's a bit more work, you first have to create an expression of field bitop value and then use that expression to compare it to a value.

Got that far, but am struggling with the object model a little


RelationPredicateBucket bkt = new RelationPredicateBucket();    
bkt.Relations.Add(ForSaleEntity.Relations.AppraisalEntityUsingForSaleID);

Expression maskBitWiseAnd = new Expression(EntityFieldFactory.Create(ApplicantFieldIndex.PreferenceMask),
    ExOp.BitwiseAnd,LURequirementsListManager.Operations.Fetch("Price").IndexID - 1);

Expression maskBitWiseTrue = new Expression(maskBitWiseAnd,ExOp.NotEqual,0);

Expression maskBitWiseFalse = new Expression(EntityFieldFactory.Create(ApplicantFieldIndex.PreferenceMask),
    ExOp.BitwiseAnd,LURequirementsListManager.Operations.Fetch("Price").IndexID - 1);
    
PredicateExpression maskFalseTest = new Expression(maskBitWiseTrue,ExOp.Equal,0);

PredicateExpression maskTest = new PredicateExpression()
maskTest.AddWithAnd(PredicateFactory.CompareValue(ApplicantFieldIndex.PriceFrom,
    ComparisonOperator.GreaterEqual,((AppraisalEntity)forsale.Appraisal[0]).AskingPrice));
maskTest.AddWithAnd(PredicateFactory.CompareValue(ApplicantFieldIndex.PriceTo,
    ComparisonOperator.LessEqual,((AppraisalEntity)forsale.Appraisal[0]).AskingPrice));     

I figure that is the correct way of building up the expressions and predicates for the query, but am having problems working out how to combine them.

Ryan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 02-Jun-2005 11:05:38   

The expression: (([Applicant].[PreferenceMask] & 1) != 0) should be formulated as: Field != 0, and you apply the expression Field & 1 to the field. So, you'll do:


EntityField2 field = EntityFieldFactory.Create(ApplicantFieldIndex.PreferenceMask);
field.ExpressionToApply = new Expression(EntityFieldFactory.Create(ApplicantFieldIndex.PreferenceMask), ExOp.BitwiseAnd, 1);
FieldCompareValuePredicate firstFilter = new FieldCompareValuePredicate(field, null, ComparisonOperator.NotEqual, 0);

Then: (([Applicant].[LocationMask] & 8 ) != 0) should be formulated as:


EntityField2 field2 = EntityFieldFactory.Create(ApplicantFieldIndex.LocationMask);
field2.ExpressionToApply = new Expression(EntityFieldFactory.Create(ApplicantFieldIndex.LocationMask), ExOp.BitwiseAnd, 8);
FieldCompareValuePredicate secondFilter = new FieldCompareValuePredicate(field2, null, ComparisonOperator.NotEqual, 0);

Then: ([Applicant].[PreferenceMask] & 1) = 0) should be formulated as: (re-using expression field)


FieldCompareValuePredicate thirdFilter = new FieldCompareValuePredicate(field, null, ComparisonOperator.Equal, 0);

Then, build the predicate expressions. First: (([Applicant].[PreferenceMask] & 1) != 0) AND (([Applicant].[LocationMask] & 8 ) != 0)


PredicateExpression andPredicate = new PredicateExpression(firstFilter, PredicateExpressionOperator.And, secondFilter);

As the Or predicate is already done, we can add it to the complete filter:


PredicateExpression completePredicate = new PredicateExpression(andPredicate, PredicateExpressionOperator.Or, thirdFilter);

so, in full, it looks like:


EntityField2 field = EntityFieldFactory.Create(ApplicantFieldIndex.PreferenceMask);
field.ExpressionToApply = new Expression(EntityFieldFactory.Create(ApplicantFieldIndex.PreferenceMask), ExOp.BitwiseAnd, 1);
FieldCompareValuePredicate firstFilter = new FieldCompareValuePredicate(field, null, ComparisonOperator.NotEqual, 0);

EntityField2 field2 = EntityFieldFactory.Create(ApplicantFieldIndex.LocationMask);
field2.ExpressionToApply = new Expression(EntityFieldFactory.Create(ApplicantFieldIndex.LocationMask), ExOp.BitwiseAnd, 8);
FieldCompareValuePredicate secondFilter = new FieldCompareValuePredicate(field2, null, ComparisonOperator.NotEqual, 0);

FieldCompareValuePredicate thirdFilter = new FieldCompareValuePredicate(field, null, ComparisonOperator.Equal, 0);

PredicateExpression andPredicate = new PredicateExpression(firstFilter, PredicateExpressionOperator.And, secondFilter);
PredicateExpression completePredicate = new PredicateExpression(andPredicate, PredicateExpressionOperator.Or, thirdFilter);

Frans Bouma | Lead developer LLBLGen Pro
Posts: 34
Joined: 20-Apr-2005
# Posted on: 02-Jun-2005 11:40:25   

Thanks muchly Frans, normaly wouldn't try to get you to do my work for me, damn deadlines simple_smile

Ryan