views:

263

answers:

3

I know there are a lot of examples of this on the web, but I can't seem to get this to work.

Let me try to set this up, I have a list of custom objects that I need to have limited on a range of values.

I have a sort variable that changes based on some action on the UI, and I need to process the object differently based on that.

Here is my object:
MyObject.ID - Just an identifier
MyObject.Cost - The cost of the object.
MyObject.Name - The name of the object.

Now I need to filter this based on a range in the cost, so I will have something similar to this, considering that I could be limiting by Either of my bottom two properties.

var product = from mo in myobject where mo.Cost <= 10000

OR

var product = from mo in myobject where mo.Name equals strName

Now I have the dynamic linq in my project, but I'm not figuring out how to get it to actually work, as when I do some of the examples I am only getting:

Func<Tsourse>bool>predicate as an option.

Edit I am trying to find a solution that helps me Objectify my code, as right now it is a lot of copy and paste for my linq queries.

Edit @Stan Is there an obvious performance difference between:

var product = from mo in myobject 
... a few joins ...
where mo.Cost <= 10000

And

var product = (from mo in myobject 
... a few joins ...)
.AsQueryable()
.Where("Cost > 1000")
+1  A: 

Read this great post on DLINQ by ScottGu

Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)

You would need something like

var product = myobject.Where("Cost <= 10000");
var product = myobject.Where("Name = @0", strName);

If you downloaded the samples you need to find the Dynamic.cs file in the sample. You need to copy this file into your project and then add using System.Linq.Dynamic; to the class you are trying to use Dynamic Linq in.

EDIT: To answer your edit. Yes, there is of course a performance difference. If you know the variations of filters beforehand then I would suggest writing them out without using DLINQ.

You can create your own Extension Method like so.

 public static class FilterExtensions
    {
        public static IEnumerable<T> AddFilter<T,T1>(this IEnumerable<T> list, Func<T,T1, bool> filter,  T1 argument )
        {
            return list.Where(foo => filter(foo, argument) );
        }
    }

Then create your filter methods.

        public bool FilterById(Foo obj, int id)
        {
            return obj.id == id;
        }

        public bool FilterByName(Foo obj, string name)
        {
            return obj.name == name;
        }

Now you can use this on an IEnumerable<Foo> very easily.

    List<Foo> foos = new List<Foo>();
    foos.Add(new Foo() { id = 1, name = "test" });
    foos.Add(new Foo() { id = 1, name = "test1" });
    foos.Add(new Foo() { id = 2, name = "test2" });

    //Example 1
    //get all Foos's by Id == 1
    var list1 = foos.AddFilter(FilterById, 1);

    //Example 2
    //get all Foo's by name ==  "test1"
    var list2 = foos.AddFilter(FilterByName, "test1");

    //Example 3
   //get all Foo's by Id and Name
   var list1 = foos.AddFilter(FilterById, 1).AddFilter(FilterByName, "test1");
Stan R.
Read my question, I said I have that in my project but can't get it to actually work.
Clarence Klopfstein
That's because you need to actually use the DLINQ extension methods.
Stan R.
What does that mean? If I understood what I was doing wrong, I wouldn't be asking here.
Clarence Klopfstein
If it, is using the . As I said, every time I type that... I get the Func<... in my intellisense and not the dynamic options.
Clarence Klopfstein
You downloaded DLINQ, but have you added it as a reference to your project and use the correct namespace?
Stan R.
I added the dynamic.cs to my business layer DLL, and added the namespace. I can get it to show if I put .asqueryable() on my objects, but in the overall solution I have that isn't realistic where I need to use it.
Clarence Klopfstein
@Clarence, thats because if you look at the source code you will see that the extension methods all extend `IQueryable` rather than `IEnumerable` this is why you don't see the methods unless you use `AsQueryable()` method.
Stan R.
I am going to edit my question a bit, to see if you could help answer a follow up to this that isn't appropriate for a comment.
Clarence Klopfstein
@Clarence, I updated my answer, hope you find the code sample useful
Stan R.
@Stan, thank you for your help. Gave you a +1, but the solution offered by @Aaron was a bit more fitting for my situation. Though your solution was totally acceptable as well.
Clarence Klopfstein
+3  A: 

Maybe not directly answering your question, but DynamicQuery is unnecessary here. You can write this query as:

public IEnumerable<MyObject> GetMyObjects(int? maxCost, string name)
{
    var query = context.MyObjects;
    if (maxCost != null)
    {
        query = query.Where(mo => mo.Cost <= (int)maxCost);
    }
    if (!string.IsNullOrEmpty(name))
    {
        query = query.Where(mo => mo.Name == name);
    }
    return query;
}

If the conditions are mutually exclusive then just change the second if into an else if.

I use this pattern all the time. What "Dynamic Query" really means is combining pure SQL with Linq; it doesn't really help you that much with generating conditions on the fly.

Aaronaught
I think was just using those `where` as mere examples, i think he means that he may have many different filters.
Stan R.
@Stan: It doesn't matter how many different filters there are, you can keep building up the expression this way indefinitely. Under the hood, this is exactly what writing a regular `from x in y` query expression does, but without the conditionals. DynamicQuery is only for use when you need to write your queries as strings; if you're using lambda expressions, you don't need it.
Aaronaught
@Aaronaught, you can't keep writing many different filters as there maybe an enormous amount of variations. Say you have 5 fields that's more than 200 possible filter combination's.
Stan R.
@Stan: If you have 5 fields, that's 5 `if` statements. The number of possible combinations does not matter - and even if it did, how would DynamicQuery help? Don't get me wrong, DynamicQuery is a great add-on, it's just not needed here.
Aaronaught
This is somewhat what I was looking for, and I am going to give this a shot. I do have a limited number of possibilities, so this would be very maintainable.
Clarence Klopfstein
@Aaronaught, i do agree with you...this is why I changed my answer.
Stan R.
A: 
using System.Linq;

var products = mo.Where(x => x.Name == "xyz");

var products = mo.Where(x => x.Cost <= 1000);

var products = mo.Where(x => x.Name == "xyz" || x.Cost <= 1000);
Kris Krause