0

I know about dynamic LINQ, but I'm wondering if there's a way to do this without building up a string of a query. I'd like to be able to use all of those nice built in LINQ calls like Contains, Count, Distinct, etc without having to worry about the SQL needed to create them. What I want to do is:

AdventureWorks2008R2Entities AWE = new AdventureWorks2008R2Entities();
var query = AWE.Employees.AsQueryable();
object FieldToQuery = ?;
if (textBox1.Text != "") query = query.Where(x => x.FieldToQuery.Contains(textBox1.Text));

Is something like this possible some how, or is it going against the fundamentals of LINQ?

cost
  • 4,420
  • 8
  • 48
  • 80
  • 3
    You need to build an expression tree by hand. – SLaks Sep 11 '13 at 21:51
  • 1
    What you want to do just generally isn't an option without reflection. There's no simple way to refer to a field/property aside from statically referencing it at compile time with the access operator. – evanmcdonnal Sep 11 '13 at 21:52
  • 1
    `AdventureWorks2008R2Entities AWE = new AdventureWorks2008R2Entities();` - that's why the `var` keyword was introduced in C#. – Federico Berasategui Sep 11 '13 at 21:54
  • @evanmcdonnal completely untrue. – Federico Berasategui Sep 11 '13 at 21:55
  • @HighCore Old habits and all that. My first experience with `var` was from a programmer that used it exclusively, and sometimes it made his code hard to work with. You're right in this case though, var would be well suited here. And as to your response to evanmcdonnal, are you saying this can't be done with reflection? – cost Sep 11 '13 at 21:58
  • @cost I'm saying, to quote SLaks, `you need to build an expression tree by hand`. – Federico Berasategui Sep 11 '13 at 21:58
  • @HighCore That's what I was afraid of. I've been trying to duplicate a feature of WCF RIA services that lets me build data filters dynamically like this, but it doesn't look like it works that way here. – cost Sep 11 '13 at 22:00
  • @HighCore so without reflection how do you select a property to access at run time? – evanmcdonnal Sep 11 '13 at 22:11
  • 1
    @evanmcdonnal `Expression> expr = x => x.Name == "Something";`. This is not java, dude. Reflection is always the last resort, when all other options have been exhausted. – Federico Berasategui Sep 11 '13 at 22:14
  • @HighCore @evanmcdonnal There is no difference in the compiled code between using `var` and using an explicitly typed variable. The compiler still treats the variable as the type of whatever was on the other side of the `=`: `var i = 5;i = "abcd";` will raise a compilation error, because the type of variable `i` is `Int32`. – Zev Spitz Sep 12 '13 at 21:21
  • @HighCore @evanmcdonnal The main benefit of `var` is that when I don't know the name of the compiled type (because it's an anonymous type and the compiler has given it an autogenerated name which I don't know) I can still statically refer to type members. See [here](http://stackoverflow.com/a/6281809/111794). The characters I save when typing `var` instead of `SomeTypeWithAReallyLongName` is a side benefit. – Zev Spitz Sep 12 '13 at 21:22
  • @ZevSpitz I already know that, dude. – Federico Berasategui Sep 12 '13 at 21:23
  • @HighCore "AdventureWorks2008R2Entities AWE = new AdventureWorks2008R2Entities(); - that's why the var keyword was introduced in C#."??? – Zev Spitz Sep 12 '13 at 21:24
  • @ZevSpitz reword it as you like, dude – Federico Berasategui Sep 12 '13 at 21:25
  • It is however poossible to tell the compiler not to assign **any** type to the variable (not even `object`) and access to all members will be purely at runtime, using the `dynamic` keyword. But `dynamic` cannot be used within an expression. – Zev Spitz Sep 12 '13 at 21:29
  • @ZevSpitz I already know that, dude. – Federico Berasategui Sep 12 '13 at 21:30

2 Answers2

0

Consider using PredicateBuilder from LINQKit as an easier alternative to building the expression tree by hand:

var predicate = PredicateBuilder.True<Employee>();
if (textBox1.Text != "") {
    var txt = textBox1.Text;
    predicate = predicate.And(e => e.Field1ToQuery.Contains(txt));
}
if (textBox2.Text != "") {
    var txt = textBox2.Text;
    predicate = predicate.And(e => e.Field2ToQuery.Contains(txt));
}

var AWE = new AdventureWorks2008R2Entities();
var query = AWE.Employees.AsExpandable().Where(predicate);

(The var txt is needed because under the covers these expressions are translated into the corresponding SQL (simplified):

SELECT *
FROM Employees
WHERE Field1ToQuery LIKE '%' + @p_1 + '%'

where the parameters are filled with the value of the variable. SQL Server has no knowledge of the textbox on the client-side -- the following SQL will fail:

SELECT *
FROM Employees
WHERE Field1ToQuery LIKE '%' + textBox1.Text + '%'

and (I suppose) passing the entire textbox as a parameter would be too complex.)

Zev Spitz
  • 13,950
  • 6
  • 64
  • 136
0

You can use https://github.com/PoweredSoft/DynamicLinq

Nuget package https://www.nuget.org/packages/PoweredSoft.DynamicLinq/

And do

queryable.Query(t => t.Contains("PropertyOrField", "search value"));

if you want to query multiple fields you can do

queryable.Query(t => t.Contains("FirstName", "Dav").OrContains("FirstName", "Jo"));
David Lebee
  • 596
  • 4
  • 14