views:

267

answers:

1

Helo,

i have the following code which should filter entities. Half of the code is working by i'm trying to refactor my code to get some sort of 'subfilters'.

Basically i have the following call to filter a Users entity collection:

var result = ctx.GetUsers().WithGroups("Administrators","Users").ToList();

WithGroups has the following definition which works:

public static IQueryable<User> WithGroups(this IQueryable<User> users, params string[] groups)
{
    if (groups != null && groups.Length > 0)
    {

        var outer = PredicateBuilder.True<User>();
        var inner = PredicateBuilder.False<Group>();
        foreach (string group in groups)
        {
            string g1 = group;
            inner = inner.Or(g => g.Name == g1);
        }
        outer = outer.And(u => u.Groups.Where(inner.Compile()).Any());
        users = users.Where(outer);               
    }
    return users;
}

I'm now trying to create a filter on the Groups entities named "WithNames" which i may call within "WithGroups" to get better code. It is defined like so, which works when called directly:

public static IQueryable<Group> WithNames(this IQueryable<Group> groups, params string[] names)
{
    if (names != null && names.Length > 0)
    {
        var outer = PredicateBuilder.True<Group>();
        var inner = PredicateBuilder.False<Group>();
        foreach (var name in names)
        {
            string _n = name;
            inner = inner.Or(g => g.Name == _n);
        }
        groups = groups.Where(outer.And(inner.Expand()));
    }
    return groups;
}

var test = ctx.GetGroups().WithNames("Administrators").ToList();

I have tried this one (and some others) which doesn't work because Linq to Entities doesn't know "WithNames":

public static IQueryable<User> WithGroups(this IQueryable<User> users, params string[] groups)
{
    if (groups != null && groups.Length > 0)
    {
        var inner = PredicateBuilder.False<User>();
        inner = inner.And(u => u.Groups.AsQueryable().AsExpandable().WithNames(groups).Any());
        users = users.Where(inner.Expand());
    }
    returnh users;
}

Perhaps someone may point me to a solution. I don't have any more ideas to find a way to get around this.

Thx

+1  A: 

If you change (or overload) your WithNames and WithGroups to return Expression<Func<Group, bool>> instead of IQueryable<Group> (and similarly for Users, then you can use both of them inside calls to Where. As you've discovered, L2E won't parse (this would essentially require decompiling it) a method, but it can handle an Expression.

Craig Stuntz
Thanks, this works, but doesn't fit into my current repository structure, because it should be some sort of chainig WithXY methods which return IQueryable. But i'm checking a solution which is working with a criteria object. So one writes a query like this: `repo.GetUsers(c => c.WithGroup("Administrators")).ToList()` The Cirteria object chains expressions, so i think your solution fit's in there.
Claus Trojahn