2

I am currently developing a Staff management system for my company. The fields may vary and change time to time, so I have an interface for each field like this:

public interface IStaffInfoField
{

    // ...

    IQueryable<Staff> Filter(IQueryable<Staff> pList, string pAdditionalData);

    // ...

}

For each field, I implement the Filter method, for example with Name:

class NameStaffInfoField : BaseStaffInfoField
{

    // ...

    public override IQueryable<Staff> Filter(IQueryable<Staff> pList, string pAdditionalData)
    {
        return pList.Where(q => q.Name.Contains(pAdditionalData));
    }

    // ...

}

Now the users want to search with multiple conditions, it's easy, I just iterate through the list and call Filter. However, they also want a OR condition (say, staff which have name A, OR name B, AND Department Name C, OR Age 30). Note: Users are end-users and they input the search queries through comboboxes and textboxes.

Can I modify my pattern or the lambda expression somehow to achieve that? Because throughout the progress, I don't save the original list to Union it for OR condition. I think it will be slow if I save the expression and Union it for OR condition.

The only solution I can think of now is to add a method to interface that require raw SQL WHERE statement. But my entire program hasn't used pure SQL query yet, is it bad to use it now?

0

3 Answers 3

3

Since your method returns IQueryable, clients already can use it for arbitrarily complicated queries.

IQueryable<Staff> result = xxx.Filter( .... );

result = result.Where( ... );
if ( ... )
    result = result.Where( s => ( s.Age > 30 || s.Salary < 1 ) && s.Whatever == "something" );

The IQueryable is very flexible. The query tree is evaluated and translated to sql when you start to enumerate results.

I only wonder why would you need the interface at all?! Since your Filter method expects the IQueryable, this means that client already has the IQueryable! Why would she call your Filter method then if she can already apply arbitrarily complicated query operators on her own?

Edit:

After your additional explanation, if I were you I would create a simple interface to let users create their own query trees containing OR and AND clauses and create a simple function that would translate the user query tree to linq expression tree.

In other words, do not let end users work at linq query tree level, this is too abstract and also too dangerous to let users touch such low level layer of your code. But abstract trees manually translated to linq trees sound safe and easy.

Sign up to request clarification or add additional context in comments.

3 Comments

Sorry, the users are the end users, not developers. The end-user is provided a list of comboboxes and textboxes to enter their search query. That's why I don't know the expression yet (in your example, ` s => ( s.Age > 30 || s.Salary < 1 ) && s.Whatever == "something" `
I am the one that need to generate the expression like that, that's why I need interface (because the fields are unknown, maybe tomorrow they want to manage their staff Relationship, who know).
That little details changes everything :)
2

You can download Albahari's LINQKit. It contains a PredicateBuilder that allows you, among other useful things, to concatenate LINQ expressions with OR in a dynamic way.

var predicate = PredicateBuilder.False<Staff>();
predicate = predicate.Or(s => s.Name.Contains(data));
predicate = predicate.Or(s => s.Age > 30);
return dataContext.Staff.Where(predicate);

You can also download the source code and see how it is implemented.

1 Comment

Yes! This is what I wanted to do, but I didn't know how to implement it. Thank you very much!
0

If your users are end users, and they enter criteria through a UI, you may want to look at a UI control that supports IQueryable. Telerik has a large number of pre-baked controls. In most cases end users interact with a grid and they apply filters to the columns. There are several other vendors that do the same thing.

A second option, if you want to make your life difficult, you could take the input text that the user supplies, parse it into a expression tree and then map that expression tree to a IQueryable. If you are not familiar with parsers this task will be fairly difficult to implement.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.