tags:

views:

58

answers:

3

I'm trying to build a complex query with linq.

I have a C# method that takes in parameters some arguments:

public void function returnAList(string arg1, string arg2, 
    string arg3, string arg4);

I put the following code that lets me return a list from my database:

List<Person> listOfPersons = this.businessLayer.ReturnPersons();
var persons= from p in listOfPersons
  select new
  {
    FirstName = p.FirstName,
    LastName = p.LastName,
    Age = p.Age,
    Address = p.Address,
    PhoneNumber = p.PhoneNumber
  };

What I want, is to inject my args in the query so that I can obtain the following algorithm:

List<Person> listOfPersons = this.businessLayer.ReturnPersons();
    var persons= from p in listOfPersons 
    where (
      if (arg1 isNotNull)
        (p.FirstName == arg1)
      if (arg2 usNotNull)
        (p.LastName == arg2) 
      ...
     )
      select new
      {
        FirstName = p.FirstName,
        LastName = p.LastName,
        Age = p.Age,
        Address = p.Address,
        PhoneNumber = p.PhoneNumber
      };

Is there a way to do that?

+1  A: 

Typically you do like this:

IEnumrable<Person> listOfPersons = this.businessLayer.ReturnPersons();

if (arg1 isNotNull)
    listOfPersons = listOfPersons.Where(p=> p.FirstName == arg1);
if (arg2 usNotNull)
    listOfPersons = listOfPersons.Where(p=> p.LastName == arg2);
...

var persons= from p in listOfAPerson
  select new
  {
    FirstName = p.FirstName,
    LastName = p.LastName,
    Age = p.Age,
    Address = p.Address,
    PhoneNumber = p.PhoneNumber
  };
Albin Sunnanbo
Be careful with declaring `listOfPersons` as an `IEnumerable`. Extension methods aren't polymorphic so IEnumerable.Where isn't the same things as IQueryable.Where. This would pull the entire collection from the DB and then apply an in-memory sort on it. Depending on the number of rows that could turn into a very expensive operation.
R0MANARMY
@R0MANARMY, Yes, that is correct, but since it was returned as a List before IQueryable would not be possible without changing the signature of ReturnPersons.
Albin Sunnanbo
@Albin Sunnanbo: Good point.
R0MANARMY
+1  A: 
var persons = from p in listOfPersons
where arg1 == null || p.FirstName == arg1
   && arg2 == null || p.LastName == arg2
   && ...
  select new
  {
    FirstName = p.FirstName,
    LastName = p.LastName,
    Age = p.Age,
    Address = p.Address,
    PhoneNumber = p.PhoneNumber
  };

Albin's suggestion is also a good way to do it

Thomas Levesque
A: 

Difficult to do portably with the syntax you have.

If you make the function take arsg as params, you could do:

var persons= from p in listOfAPerson
  where args.Where(arg=>arg!=null).Contains(p.FirstName)
  select new
  {
    FirstName = p.FirstName,
    LastName = p.LastName,
    Age = p.Age,
    Address = p.Address,
    PhoneNumber = p.PhoneNumber
  };

You haven't specified what your function arguments mean, however. What are arg3 and arg4? Is arg3 to be compared to a FirstName and arg4 to be compared to a LastName, or something else?

Tom W
Yes. Each argument corresponds to a field in my object.
Zakaria