简体   繁体   中英

LINQ Dynamic Where - Not adding clause

I have the following code:

public OTestTable GetTestCode(Func<TestTable, bool> whereClause)
{
    return CoreContext.TestTables.Where(whereClause).Select(TestTableMap.DataToObject).FirstOrDefault();
}

CoreContext is my data context (which is initialized in a base class)

My TestTableMap is as follows:

public class TestTableMap
{
    public static readonly Func<TestTable, OTestTable> DataToObject = mapper =>
       new OTestTable
       {
           Code = mapper.mycode 

       };
}

Then in my business method i have the following:

public OTestTable GetTestCode(string code)
{
    return QueryEngine.GetTestCode(id => id.mycode == code);
}

From my main program, i am calling GetTestCode with a string value.

When I watch SQL profiler, I get the following:

SELECT [t0].[mycode]
FROM [dbo].[TestTable] AS [t0]

It does not have the where clause appended to the SQL query. If i add the where clause to the LINQ as var query = from c in DataContext.TestTable where c.mycode == '' select c;

It will add the where clause.

However, when I run my code, it will return the correct record, but it seems like I am pulling back all records from the database and filtering in my code (which should not happen).

Any thoughts with what I am doing wrong?

Thanks

In order to construct SQL statements, LINQ to SQL requires an expression tree. Func<TestTable, bool> does not represent an expression tree, it is a "black box" function pointer. LINQ cannot do anything intelligent with this apart from blindly execute it on an in-memory collection.

You need to do this instead:

public OTestTable GetTestCode(Expression<Func<TestTable, bool>> whereClause) {
    return CoreContext.TestTables.Where(whereClause).Select(TestTableMap.DataToObject).FirstOrDefault();
}

This code compiles using the Queryable.Where extension method, which does accept an expression tree, rather than the Enumerable.Where extension method, which only accepts a raw delegate.

Try creating your where clause as:

Expression<Func<T, bool>> whereClause

Where the T parameter is your source type Table<T> source

Also see the PredicateBuilder here: http://www.albahari.com/nutshell/predicatebuilder.aspx

It provides you convenient extension methods to predicate IQueryable<T> . like this:

var predicate = PredicateBuilder.True<Family>();
predicate = predicate.And(o => o.Birthday < new DateTime(1980, 1, 1));
                     .Or(o => o.Name.Contains("ke"));
var result = Source.Where(predicate).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM