We have introduced three applications of Linq: Linq to SQL, Linq to XML, and Linq to Object. This article introduces the implementation methods and application scenarios of dynamic Linq.
Namespace:
System. Linq;
System. Linq. Expressions;
We all know that only Lambda expressions are required when applying Linq. However, in some scenarios, it is not enough or inconvenient to use only the field names of Data models.
Scenario 1: If we need to splice the Where condition for query, We can splice the IQueryable expression in one way. But I want to directly splice a Where condition as I write an SQL statement. How can I implement Linq?
Scenario 2: if we want a list, the list can be sorted by each header. We pass the table header as a parameter to the sorting function. How can we implement it inside the function? You can compare the enumerated values one by one. Write different Linq statements for different columns, but the code is redundant. How do I implement dynamic field names in a traditional way?
Next, we will talk about another method of applying Linq: Dynamic Linq, using Linq. Expressions. Scenario 1. I just want to use Where to splice (table name parameter) to complete the operation. Let's take a look at the implementation below. All of the following demos are only used in Linq to SQL. If they are Entity frameworks, they may be different.
DataClasses1DataContext dbContext = new DataClasses1DataContext ();
Public string dynamicLinq (int id = 50)
{
IQueryable <DataListForDemo> dLinq = dbContext. DataListForDemos;
ParameterExpression paraExpr = Expression. Parameter (typeof (DataListForDemo), "data ");
MemberExpression propExpr = Expression. Property (paraExpr, typeof (DataListForDemo). GetProperty ("ID "));
BinaryExpression filter = Expression. LessThan (propExpr, Expression. Constant (id ));
LambdaExpression lambdaWhere = Expression. Lambda (filter, paraExpr );
MethodCallExpression Where = Expression. Call (typeof (Queryable ),
"Where ",
New Type [] {typeof (DataListForDemo )},
Expression. Constant (dLinq ),
LambdaWhere
);
Var data0 = dLinq. AsQueryable (). Provider. CreateQuery (Where );
DbCommand comm = dbContext. GetCommand (data0 );
DbContext. Log (comm. CommandText );
Return comm. CommandText;
}
The above is a variety of Linq. expression class. ParameterExpression is used to define the parameter, that is, the object to be operated. PropertyExpression is used to define the attribute, that is, the field to be operated. BinaryExpression is used to define the condition query Expression, that is, the Where condition, use LambdaExpression to define the Lambda expression, that is, the IQueryable object. The last step is to complete the call. the Call method is used to define your expression methods, such as Where, Select, OrderBy, GroupBy, All, Any, Equal, etc, if you have any dynamic requirement, you can write this method. There are not many instances on MSDN, but you can find a lot on the Internet.
The generated SQL statement is returned. The SQL statement is as follows:
SELECT [t0]. [ID], [t0]. [col1], [t0]. [col2], [t0]. [col3], [t0]. [col5], [t0]. [col4]
FROM [dbo]. [DataListForDemo] AS [t0]
WHERE [t0]. [ID] <@ p0
Comparing the generated SQL statements and Expression expressions, it is easy to understand how the implementation and operation of Linq work. some people may ask that the IQueayable and IEnuerable objects will all carry a Linq expression, instead of a separate method, which can be implemented by passing parameters, to implement this method, we need to mention what is the extension method and how to implement the extension method. in C #, the method for extending an object can be the override base class method. But how can I extend the methods for such objects as string and iqueryable? Of course, the Override base class does not work. In this case, we need to use the this keyword, which is another application method of this.
To use the extension method, first write a static class and define a static method in the static class. The first parameter in the static method starts with this, the first parameter is the system object to be extended.
For example:
Public static class DynamicQueryable
{
// Method for extending the IQueryable object
Public static IQueryable Where (this IQueryable source, string predicate, params object [] values)
{
If (source = null) throw new ArgumentNullException ("source ");
If (predicate = null) throw new ArgumentNullException ("predicate ");
LambdaExpression lambda = DynamicExpression. parselamate (source. ElementType, typeof (bool), predicate, values );
Return source. Provider. CreateQuery (
Expression. Call (
Typeof (Queryable), "Where ",
New Type [] {source. ElementType },
Source. Expression, Expression. Quote (lambda )));
}
Public static LambdaExpression ParseLambda (Type itType, Type resultType, string expression, params object [] values)
{
Return parselameter (new ParameterExpression [] {Expression. Parameter (itType, "")}, resultType, expression, values );
}
}
The IQueryabler method is extended, so all objects of the IQueryable type have the dynamic Where function. I don't know why the Microsoft team didn't add this function, but only provided the Expressions class, with these dynamic expressions, the Linq function will be very strong.
Let's take a look at the call:
Public string SelectDynamic (int id = 0)
{
DataListForDemo model = dbContext. DataListForDemos. Where ("ID =" + id. ToString (). SingleOrDefault ();
Return model. ID. ToString ();
}
One obvious change now is that the Where clause can only write one join where condition, and it is a string. This is what most Programmers think!
All existing methods in Linq can be expanded and implemented in this way, and more implementation methods can be Google. Google is recommended. Some English articles are well written, rich resources.