when using the method below for an OR operation, I am getting back duplicate records. do I have to specify a custom IEqualityComparer? a simple distinct() does not work
internal static IQueryable<T> FilterEntity<T>(filters filters, IQueryable<T> entities)
{
if (filters.groupOp == "AND")
foreach (var rule in filters.rules)
entities = entities.Where<T>(
rule.field, rule.data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
);
else
{
//Or
IQueryable<T> temp = (new List<T>()).AsQueryable();
foreach (var rule in filters.rules)
{
var t = entities.Where<T>(
rule.field, rule.data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
);
temp = temp.Concat<T>(t).AsQueryable();
}
entities = temp;
}
return entities;
}
EDITED AFTER SUGGESTION FROM @usr below – This gives me the correct query in sql profiler (with a distinct) but this starts to look too convoluted – I wd like a cleaner solution
internal static IQueryable<T> FilterEntity<T>(filters filters, IQueryable<T> entities)
{
if (filters.groupOp == "AND")
foreach (var rule in filters.rules)
entities = entities.Where<T>(
rule.field, rule.data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
);
else
{
//Or
var t1 = entities.Where<T>(filters.rules[0].field,filters.rules[0].data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation),filters.rules[0].op)
);
for (int i = 1; i<filters.rules.Count(); i++)
{
var t = t1.Where<T>(filters.rules[i].field, filters.rules[i].data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation), filters.rules[i].op)
);
t1.Concat<T>(t).AsQueryable();
}
entities = t1;
}
return entities.Distinct<T>();
}
This is not related to
Distinct()orIEqualityComparer. It is the modified closure gotcha, that is: the loop variablerulemust be copied in the loop body:You can follow Usr’s advice by doing this:
I wonder if it solves your issue. Note the use of
Union(which is an implicitDistinct). If it does not solve your issue I think there is some code invisible to us (e.g. in yourWhereOperation) that interferes.