- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
FieldCompareSetPredicate
Hi, I am using LLBLGen 2.5 Final with C# and SQL Server 2005. I need to use the predicate system to achieve the same results as the query below. I am pretty sure that I need to use the FieldCompareSetPredicate and I thing that I am going to need to add filters in a loop. The number of subqueries is dynamic depending on the number of attributes that will be used in the filter. The table that the query is written against looks like:
Column_name Type Length
----------------------------- ---------------- ------
UID uniqueidentifier 16
ConfigAttributeValueGroupUID uniqueidentifier 16
ConfigAttributeUID uniqueidentifier 16
Value varchar 256
And here's the query. It returns just one record.
DECLARE @PRODUCT UNIQUEIDENTIFIER DECLARE @FIXTTYPE UNIQUEIDENTIFIER DECLARE @MOUNTING UNIQUEIDENTIFIER DECLARE @GROUPDESCRIPTION UNIQUEIDENTIFIER DECLARE @SIZE UNIQUEIDENTIFIER DECLARE @LAMPTYPE UNIQUEIDENTIFIER
SELECT @PRODUCT = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 1 AND NAME = 'CLN4_PRDTYPE_R' SELECT @FIXTTYPE = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 1 AND NAME = 'CLN4_VSR_R' SELECT @MOUNTING = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 0 AND NAME = 'Mounting' SELECT @GROUPDESCRIPTION = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 0 AND NAME = 'Group Name' SELECT @SIZE = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 0 AND NAME = 'Size - In/Outdoor' SELECT @LAMPTYPE = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 0 AND NAME = 'Lamp Type'
SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @PRODUCT AND ([VALUE] = 'R' OR [VALUE] = '') AND CONFIGATTRIBUTEVALUEGROUPUID IN (SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @FIXTTYPE AND ([VALUE] = '02' OR [VALUE] = '') AND CONFIGATTRIBUTEVALUEGROUPUID IN (SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @MOUNTING AND ([VALUE] = 'P1R30' OR [VALUE] = '') AND CONFIGATTRIBUTEVALUEGROUPUID IN (SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @GROUPDESCRIPTION AND ([VALUE] = 'SUSPENDED' OR [VALUE] = '') AND CONFIGATTRIBUTEVALUEGROUPUID IN (SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @SIZE AND ([VALUE] = 'SO' OR [VALUE] = '') AND CONFIGATTRIBUTEVALUEGROUPUID IN (SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @LAMPTYPE AND ([VALUE] = 'CF' OR [VALUE] = ''))))))
Here is the docs for FieldCompareSetPredicate. Please try to write your routine and let us know if you have troubles with it.
The dynamic part of your problem could be resolved this way:
IRelationPredicateBucket filter = new RelationPredicateBucket();
if (someValue != null)
{
// build the FieldCompareSetPredicate
// ...
filter.Add(theSomeValueFCSPFilter);
}
if (someOtherValue != null)
{
// same here...
}
Or a loop, if it accommodates better
I've never used IRelationPredicateBucket before. Sorry I failed to mention that I am using SelfServicing. Can I use the Bucket under self servicing?
Here's what I have come up with so far. It is not working correctly yet. It should return only one result.
PredicateExpression filter = new PredicateExpression();
ConfigAttributeValueCollection attVals = new ConfigAttributeValueCollection();
List<PredicateExpression> subQueries = new List<PredicateExpression>();
mCurrentTemplate.SetCollectionParametersPages(0, new SortExpression
(DrawingLayoutPageFields.PrintOrder | SortOperator.Ascending));
foreach (ConfigAttributeEntity attribute in mCurrentTemplate.Pages[0].Sections
[0].Attributes)
{
PredicateExpression p = new PredicateExpression();
p.Add(ConfigAttributeValueFields.Value == aLine.getConfigAttributeValue
(attribute.Name));
p.AddWithOr(ConfigAttributeValueFields.Value == "*");
p.AddWithAnd(ConfigAttributeValueFields.ConfigAttributeUid == attribute.Uid);
subQueries.Add(p);
}
for (int subQueryIndex = subQueries.Count - 2; subQueryIndex > -1; subQueryIndex-- )
{
subQueries[subQueryIndex].AddWithAnd(new FieldCompareSetPredicate
(ConfigAttributeValueFields.ConfigAttributeUid,
ConfigAttributeValueFields.ConfigAttributeUid, SetOperator.In, subQueries
[subQueryIndex + 1]));
}
attVals.GetMulti(subQueries[0]);
Ok, I am stuck... maybe I've just been looking at it too long. Below is my code and the (what I think to be) the comparable SQL query. I grabbed the values when running the code and plugged them into the SQL query. The query returns one result, which is what I expect. Whent the code executes, attVals contains 300 entities after call GetMulti(). Can anyone point me in the right direction?
Here's my code:
PredicateExpression filter = new PredicateExpression();
ConfigAttributeValueCollection attVals = new ConfigAttributeValueCollection();
List<PredicateExpression> subQueries = new List<PredicateExpression>();
mCurrentTemplate.SetCollectionParametersPages(0, new SortExpression(DrawingLayoutPageFields.PrintOrder | SortOperator.Ascending));
StringBuilder sb = new StringBuilder();
foreach (ConfigAttributeEntity attribute in mCurrentTemplate.Pages[0].Sections[0].Attributes)
{
PredicateExpression p = new PredicateExpression();
if (attribute.IsConfigAttribute)
{
p.Add(ConfigAttributeValueFields.Value == aLine.getConfigAttributeValue(attribute.Name));
sb.Append(attribute.Name + " = " + aLine.getConfigAttributeValue(attribute.Name) + " or " + "*\n");
}
else
{
p.Add(ConfigAttributeValueFields.Value == aLine.getAttributeValue(attribute.Name));
sb.Append(attribute.Name + " = " + aLine.getAttributeValue(attribute.Name) + " or " + "*\n");
}
p.AddWithOr(ConfigAttributeValueFields.Value == "*");
p.AddWithAnd(ConfigAttributeValueFields.ConfigAttributeUid == attribute.Uid);
subQueries.Add(p);
}
for (int subQueryIndex = subQueries.Count - 2; subQueryIndex > -1; subQueryIndex-- )
{
subQueries[subQueryIndex].AddWithAnd(new FieldCompareSetPredicate(ConfigAttributeValueFields.ConfigAttributeValueGroupUid, ConfigAttributeValueFields.ConfigAttributeValueGroupUid, SetOperator.In, subQueries[subQueryIndex + 1]));
}
attVals.GetMulti(subQueries[0]);
sb.Append("Returned: " + attVals.Count + " ConfigAttributeValue Entities");
Here's My SQL:
DECLARE @PRODUCT UNIQUEIDENTIFIER
DECLARE @FIXTTYPE UNIQUEIDENTIFIER
DECLARE @MOUNTING UNIQUEIDENTIFIER
DECLARE @GROUPDESCRIPTION UNIQUEIDENTIFIER
DECLARE @SIZE UNIQUEIDENTIFIER
DECLARE @LAMPTYPE UNIQUEIDENTIFIER
DECLARE @GROUPUID UNIQUEIDENTIFIER
SELECT @PRODUCT = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 1 AND NAME = 'CLN4_PRDTYPE_R'
SELECT @FIXTTYPE = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 1 AND NAME = 'CLN4_VSR_R'
SELECT @MOUNTING = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 0 AND NAME = 'Mounting'
SELECT @GROUPDESCRIPTION = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 0 AND NAME = 'Group Name'
SELECT @SIZE = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 0 AND NAME = 'Size - In/Outdoor'
SELECT @LAMPTYPE = UID FROM CONFIGATTRIBUTE WHERE ISVCATTRIBUTE = 0 AND NAME = 'Lamp Type'
SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @PRODUCT AND ([VALUE] = 'R' OR [VALUE] = '*') AND CONFIGATTRIBUTEVALUEGROUPUID IN
(SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @FIXTTYPE AND ([VALUE] = 'N' OR [VALUE] = '*') AND CONFIGATTRIBUTEVALUEGROUPUID IN
(SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @MOUNTING AND ([VALUE] = 'YR' OR [VALUE] = '*') AND CONFIGATTRIBUTEVALUEGROUPUID IN
(SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @GROUPDESCRIPTION AND ([VALUE] = 'Wall Mounted' OR [VALUE] = '*') AND CONFIGATTRIBUTEVALUEGROUPUID IN
(SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @SIZE AND ([VALUE] = 'SI' OR [VALUE] = '*') AND CONFIGATTRIBUTEVALUEGROUPUID IN
(SELECT CONFIGATTRIBUTEVALUEGROUPUID FROM CONFIGATTRIBUTEVALUE WHERE CONFIGATTRIBUTEUID = @LAMPTYPE AND ([VALUE] = 'E' OR [VALUE] = '*'))))))
Ok... well, now its working. I was screwing up the simple part... the "AND" and the "OR" I needed foo = 'blah' AND (bar = 'something' OR bar = '*') and I wa not acomplishing that with the previously posted code. Here's the modified code if anyone cares...
foreach (ConfigAttributeEntity attribute in mCurrentTemplate.Pages[0].Sections[0].Attributes)
{
PredicateExpression p = new PredicateExpression();
if (attribute.IsConfigAttribute)
{
p = new PredicateExpression((ConfigAttributeValueFields.ConfigAttributeUid == attribute.Uid) & ((ConfigAttributeValueFields.Value == aLine.getConfigAttributeValue(attribute.Name)) | (ConfigAttributeValueFields.Value == "*")));
sb.Append(attribute.Name + " = " + aLine.getConfigAttributeValue(attribute.Name) + " or " + "*\n");
}
else
{
p = new PredicateExpression((ConfigAttributeValueFields.ConfigAttributeUid == attribute.Uid) & ((ConfigAttributeValueFields.Value == aLine.getAttributeValue(attribute.Name)) | (ConfigAttributeValueFields.Value == "*")));
sb.Append(attribute.Name + " = " + aLine.getAttributeValue(attribute.Name) + " or " + "*\n");
}
subQueries.Add(p);
}