0

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.

Update: 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.

Update 2: 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")
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Clarence Klopfstein
  • 4,682
  • 10
  • 33
  • 47

3 Answers3

2

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
  • 120,909
  • 25
  • 266
  • 342
  • I think was just using those `where` as mere examples, i think he means that he may have many different filters. – Stan R. Jan 08 '10 at 15:32
  • 1
    @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 Jan 08 '10 at 15:37
  • @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. Jan 08 '10 at 15:47
  • @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 Jan 08 '10 at 15:54
  • 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 Jan 08 '10 at 15:57
  • @Aaronaught, i do agree with you...this is why I changed my answer. – Stan R. Jan 08 '10 at 16:11
1

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.
  • 15,757
  • 4
  • 50
  • 58
  • Read my question, I said I have that in my project but can't get it to actually work. – Clarence Klopfstein Jan 08 '10 at 15:13
  • That's because you need to actually use the DLINQ extension methods. – Stan R. Jan 08 '10 at 15:14
  • What does that mean? If I understood what I was doing wrong, I wouldn't be asking here. – Clarence Klopfstein Jan 08 '10 at 15:16
  • 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 Jan 08 '10 at 15:17
  • You downloaded DLINQ, but have you added it as a reference to your project and use the correct namespace? – Stan R. Jan 08 '10 at 15:18
  • 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 Jan 08 '10 at 15:23
  • 1
    @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. Jan 08 '10 at 15:27
  • 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 Jan 08 '10 at 15:29
  • @Clarence, I updated my answer, hope you find the code sample useful – Stan R. Jan 08 '10 at 16:08
  • @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 Jan 08 '10 at 17:41
1
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
  • 7,304
  • 2
  • 23
  • 26