none
Reusable LINQ clauses RRS feed

  • Question

  • I am fairly new to LINQ, and am developing a web application that queries a SQL database.  My question is, what is the best way to reuse LINQ clauses?  I find myself writing the same "from customers in dc.Sales"-type statements over and over again.  Also, in the LINQ Where clause, I am typing the same lines again and again for different queries.  I don't think I have two queries that are completely identical, but I have a number of clauses that are identical and repeated.  Is there a way to write these clauses once, and just reference them from each query?  Thanks.
    Thursday, September 17, 2009 8:52 PM

Answers

  • If you want to say something like this:

    var foo = from n in numbers where n % 2 == 0 && n > 10

    then you can rewrite it so that the where clause is reusable like this:

    var predicate = new Func<int, bool>(x => x % 2 == 0 && x > 10);
    var foo = numbers.Where(predicate);
    var bar = numbers2.Where(predicate);

    • Marked as answer by Yichun_Feng Thursday, September 24, 2009 3:10 AM
    Thursday, September 17, 2009 9:19 PM

All replies

  • If you want to say something like this:

    var foo = from n in numbers where n % 2 == 0 && n > 10

    then you can rewrite it so that the where clause is reusable like this:

    var predicate = new Func<int, bool>(x => x % 2 == 0 && x > 10);
    var foo = numbers.Where(predicate);
    var bar = numbers2.Where(predicate);

    • Marked as answer by Yichun_Feng Thursday, September 24, 2009 3:10 AM
    Thursday, September 17, 2009 9:19 PM
  • Hi Tork,

     

    Add to Graeme’s post, you can use Dynamic LINQ to pass the where clause as string.

    http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

    In this way, you can pass the where statement as string.

     

    If you have any questions or concerns, please update the thread and we will have a further discussion.

     

     

    Best Regards

    Yichun Feng


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, September 21, 2009 8:24 AM
  • Thanks a lot.  I was able to use this information on predicates to create an expression library with almost everything my application needs. 

    My only remaining issue is a bit odd.  I have a value in a field which must be converted from a varchar to an int, in order to perform an evaluation like GL2 > 150.  GL2 is a varchar, but to select for only values greater than 150, I am performing a Convert.ToInt32().  Unfortuntely, there is a ghost row in the table, with GL2 = "~", and an error is generated when this value is attempted to be converted to an int.  I have added a where clause to the query for GL2 != "~", but I still get the conversion error on some queries.

    I have looked at and tried a number of different "conditional" where-clause approaches, but have yet to find one that works in this case.  As I wrote in my original post, I am no LINQ expert, so it is very possible a simple explanation has escaped me.

    At one point I thought that since the predicate useage worked so well in other cases, I would just do the same for this query.  The problem is that the table from which the values are returned for this query, would requires links to not just one, but two or more other tables, and I couldn't get the expression to work.  Maybe determining how to do that would be the best solution; I don't know.

    Still, it seems simple enough; is there a good way to basically write:
        if GL2 != "~", Convert.ToInt32(GL2) > 150;
        if GL2 == "~",  GL2 != "~";

    I've looked at ternary operators and many other items, but I can't find a way to add to this existing query:

    var q = (from lob in LOB_GRP_DT
                 from gls in GLS_DT
               where
                      (gls.GL! != "Administration &&
                       lob.LOB_GRP != "Clinical"

              select new
                 {
                       lob.LOB_GRP2
                 }

    ...

    Maybe I just need a new query style, and that's fine with me, but I need one that accounts for several tables and several where clauses, as the example above is an abridged version.

    I have four tables, with links to each other, and around seven static clauses (GL2 != "X"), but just this one "conditional" clause is giving me problems.  It appears that adding GL2 != "~" does not prevent the attempt to process that value in the Convert.ToInt32(GL2) clause, so I either need to find some kind of statement that will provide a value of my choosing (if GL2 ="~", return 0; if GL2 != "~", return Convert.ToInt32(GL2),  or a better way to query the database and return a recordset.

    Any ideas?


    Thursday, September 24, 2009 4:02 AM
  • I found a solution.  For anyone else with a similar problem, a simple let clause does the trick.

    let

     

    gl2 = (gls.GL_LVL_2 != "~" ? Convert.ToInt32(gls.GL_LVL_2) : 0)

    The in the where clause:

    gl2 > 150

    Friday, September 25, 2009 1:24 AM