views:

438

answers:

3

I'm trying to create a Linq statement that queries both columns that exist on my entity as properties and those that don't but exist as columns in the database for the entity.

For example, I have a collection of Book entities. Each Book has an ID and Title property and a matching column in the database. But, lets say the table for Book also contains a column field for Author and my Book entity doesn't have this.

A normal query involving the ID and the Title might look like this:

Books.Where(b=>b.ID == 123 && b.Title == "Title")

But, I want to also dynamically add the equivalent of " AND Author = 'Name' " to the above query as well. The Author property doesn't exist on the Book object.

The extra fields and the values they should contain will actually be available in a Dictionary. So I will need to dynamically add multiple AND [FieldName] = '[Value]' conditions to the query.

It might help explain why I would need this to know that I'm using Azure Table Storage and I have overridden the serialize that turns a Book entity into the XML stored in Azure.

Edit -

I've tried using the Dynamic Linq library but it does not work.

Books.Where(b=>b.ID == 123 && b.Title == "Title").Where("Author = @0", "SomeName").ToList();

Throws: System.Linq.Dynamic.ParseException: No property or field 'Author' exists in type 'Book'.

Also,

I know using Books.AddQueryOption("$filter","Author eq 'SomeName'") works when used by itself. But I have no idea how to use AddQueryOption along with an existing Where statement.

A: 

Have a look at the Dynamic Linq library.

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

Robert Harvey
I tried this, but the library is trying to check if the entity actually contains that property for some reason.
Vyrotek
I assume you will want to execute the query at some point in time when the field does exist. Am I missing something? Check to see if the field exists prior to putting it in the SQL statement for execution.
Robert Harvey
Nope, the Property will never exist on the Book object. I want to send the query that is generated to the database and get the data back. I will handle everything in between. I KNOW that there is a column named 'author' and that the query will succeed. What about using AddQueryOption as I mentioned above?
Vyrotek
+1  A: 

Without adding Author to Book, you would either have to pass another object with Author on it:

var x = new { Author="SomeName" };  
    Books.Where(b=>b.Id == 1 && b.Title == "Alpha").Where("@1.Author == @0", "SomeName", x);

Or inherit from Book and add an Author property just for this purpose:

public class BookEx : Book {
    public string Author { get; set; }
}

Books.Cast<BookEx>().Where(b=>b.Id == 1 && b.Title== "Alpha").Where("Author == @0", "SomeName");
Richard Hein
A: 

This is not possible with LINQ

Vyrotek