views:

547

answers:

3

I’m looking for a tool that will dynamically generate Linq to Entity queries from a given entity, a Query By Entity (Example), if you will. Given an entity and the object context it belongs to, the generator returns an ObectQuery or IQueryable that could be further modified or executed. Ideally, the query builder would not directly reference Entity Model, rather it would use the object context to build the query from the model. I imagine the code looking something like this:

        QueryBuilder qb = new QueryBuilder(new EntitiesContext());
        Customer c = new Customer();
        qb.Add(c);  
        c.FirstName = "Jim";
        var qry = qb.BuildQuery();
        int total = qry.Count();

The underlying query would look something like this:

var query = from c in ctx.Customers
            where c.FirstName == "Jim"
            select c;

Does such a thing already exist somewhere? I can imagine coding something like this myself, but I would rather start using something that already exists.

+2  A: 

Hi,

I'm not exactly sure what your goals are, if you would post some more information on your context (an actual problem), but Dynamic Linq might help you constructing linq queries dynamically:

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

Wiebe

Zidad
+1  A: 

I don't really see the value in a QueryBuilder. If it's as simple as in your sample you could only use it to find exact matches. If you need more complex queries you'd probably be better of using Linq directly.

You know that you can chain your queries? That's probably not exactly what you are looking for but you could do

IQueryable<Customers> source=context.Customers;

if (...)
{
  source = from c in source
           where c.FirstName.StartsWith("Jim")
           select c;
}

if (...)
{
  source = from c in source
           where contries.Contains(c.Country)
           select c;
}

// ...
chris
+1  A: 

You can use dynamic Linq to build up your Linq expressions at run time - simply appending methods to an existing Linq query (before you execute it). Having said that, the notion of a "QueryBuilder" class is, as Chris mentioned, of questionable merit.

Strictly speaking, Linq is itself a query builder, since it takes a Linq statement and constructs a "graph" which a query provider is then able to use to do the underlying work (compiling a SQL statement for Linq-To-SQL, or enumerating objects of Linq-For-Objects). If you want to offer end-users the ability to build queries dynamically, consider creating a UI that builds the Linq statement by adding query methods like Chris pointed out. Remember that with a Linq query, you can add as many expressions as you like - the query only executes when the enumerator is tripped.

i.e. To select the oldest Customer under 65 named Jim:

Dim qry = From customer in DataContext.Customers
qry = qry.Where( Function (c as Customer) c.Name="Jim" )
qry = qry.Where( Function (c as Customer) c.Age < 65 )
qry = qry.OrderByDescending( Function (c as Customer) c.Age )
qry = qry.Take(1) 
Dim oldJim as Customer = qry.FirstOrDefault()

The FirstOrDefault method, like using ToArray or For Each, trips the enumerator and thus processes the query.

Hope this helps!

Mark