Entity Framework 4 and Linq to Entities specifications: How to code it?
I threw d开发者_开发百科own this code because it worked, but I really need to refactor to something acceptable. It accepts a set of query objects (strings that look like productid = 3) then adds them to my query. This only works for logical AND, but I will eventually need a few different logical operators (OR, NOT).
-- Idea here is add the where clause to the original query and return a new one
private static IQueryable<Product> GetFilteredQuery(string condition,
    IQueryable<Product> originalQuery)
    {
        -- REPETITION 
        if( -- Regex comparison looking for "productid = 123" --)
        {   
            returnQuery = originalQuery.Where(
                    p => p.myEntity.SelectMany(q => q.subEntity) // spec expression
                          .Any(r => r.id == foundid));           
        }
        ... (one if statement for each specification, calling this several times)
I also have this for Ordering:
private static IQueryable<Product> GetOrderedQuery( IList<string> fields,
    IQueryable<Product> originalQuery)
{
    var resultQuery = originalQuery;
    bool firstTime = true;
    foreach( var field in fields)
    {   
        -- REPETITION  
        if( field == "id")
        {    if( firstTime == true)
             {   resultQuery = resultQuery.OrderBy( p => p.id);
                 firstTime = false;
             }
             else
             {   resultQuery = resultQuery.ThenBy( p => p.id);
             }
        }
        ... (one for each field to order by)
    }
So how could I encapsulate each repetition in to a specification object where I can somehow attach this collection of specifications to my original query, including the order expressions? This is under the Linq to Entities, Entity Framework 4, and C# umbrella.
It would be really nice to do something like this, which is essentially what the above does.
var originalQuery = ...;
foreach( var spec in mySpecs)
{    originalQuery = spec(originalQuery);  //adds all the where clauses
}
originalQuery = orderSpec( originalQuery); // adds all the order fields
Links to websites, example code, would surely be appreciated.
The only thing I saw something similar was this:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
But that's not specific to EF 4. Why not convert the query to entity SQL?
- http://msdn.microsoft.com/en-us/library/bb387145.aspx
- http://msdn.microsoft.com/en-us/library/bb738683.aspx
You can create the query as a string, and append these terms to that SQL query.
HTH.
Have a look at LinqSpecs, it might do what you need, or at least give you some ideas to work with.
From what I understand you might be able to do something like:
var originalSpec = ...;
var composedSpec = originalSpec;
foreach(var spec in mySpecs)
{    
    composedSpec &&= spec;  //adds all the where clauses
}
composedSpec &&= orderSpec; // adds all the order fields
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论