In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-05 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "how to understand IQueryable and IQueryProvider interfaces in Entity Framework". In daily operation, I believe many people have doubts about how to understand IQueryable and IQueryProvider interfaces in Entity Framework. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the questions of "how to understand IQueryable and IQueryProvider interfaces in Entity Framework". Next, please follow the editor to study!
IQueryable interface
Let's talk about this interface first, because when we use EF, we often see that the return type of linq to sql statement is IQueryable. We can take a look at the structure of this interface:
The copy code is as follows:
Public interface IQueryable: IEnumerable
{
Type ElementType {get;}
Expression Expression {get;}
IQueryProvider Provider {get;}
}
Some people may be surprised that when we use this interface in the development process, we provide a lot more methods, because Microsoft provides a powerful Queryable class, of course, you should not think that this class implements IQueryable and then implements a lot of methods, if that is the case, how can those third-party libraries customize? So Queryable is just a static class that extends the IQueryable interface. The following is the author's screenshot of .net Reflector:
If readers are more careful, they will find that linq to sql does not lead to actual queries, and we start querying data from the database only when we actually start using it.
IQueryProvider interface
If we debug the EF, we will see the generated T-SQL statement. T-SQL is obtained from the expression tree analysis, and the core is the IQueryProvider interface. The following is the structure of the interface:
The copy code is as follows:
Public interface IQueryProvider
{
IQueryable CreateQuery (Expression expression)
IQueryable CreateQuery (Expression expression)
Object Execute (Expression expression)
TResult Execute (Expression expression)
}
CreateQuery is responsible for parsing the expression tree, and of course the processed result is returned in order to analyze the following statement. Of course, this is only analysis. You can get the query statement you need according to the expression tree, such as SQL or something. Only when you actually use the data will you call the Execute method. At this point, we can start the actual query based on the statements we analyzed.
Case analysis
QueryProvider class
We can never understand the principle of talking without practice, so let's give a simple example to show it. First, let's implement the IQueryProvider interface, in which we will use a Query class, which will be introduced later. First, we create a new QueryProvider class to implement the IQueryProvider interface. First, let's take a look at the CreateQuery method:
We can see the following sentence:
What it actually means is to create an instance of Query, and the generic parameter is elementType, and the parameters are this and expression.
Finally, there is the Execute method, which passes an Expression parameter and obtains the final result. Here, the author directly writes the dead value:
Query class
Only QueryProvider is not used, we also need a class that can save the state of the expression tree, and of course, the result after we parse the expression can also be saved in it, so that we can execute and return the result according to the result of our parsing in the Execute method of IQueryProvider.
But in a later process, the Expression in Query will be the expression value in QueryProvider.
OK, let's start by looking at how to analyze this LINQ statement.
First, let's take a look at the return value of Expression in Query at the beginning of execution (as shown below):
We can see that the string inside is Where (item = > (item = = 123)). From this sentence, we can see that the where in LINQ is actually using the Where method and passing it the corresponding lambda expression. After analyzing the where section, here is the FirstOrDefault section.
Analyze FirstOrDefault
When we execute to FirstOrDefault, we can look at the value of t and find that t is actually the return value of CreateQuery in QueryProvider.
Then we start to execute the following FirstOrDefault method and find that we will once again get the value of Expression, and at this time the value of Expression is the parameter expression passed to us by CreateQuery above.
At this point, a simple process is over, and finally the value of 123 written by the author is returned.
Through the above example we have a basic understanding of its work process, next we will analyze our where item = 123step by step, of course, we will use recursion, so please organize your own ideas, step by step to see how to analyze this statement from an expression tree.
Actual combat of analyzing expression tree
First of all, we have a method to analyze the expression tree, which we will put in QueryProvider for a while:
The copy code is as follows:
Public void Analysis_Expression (Expression exp)
{
Switch (exp.NodeType)
{
Case ExpressionType.Call:
{
MethodCallExpression mce = exp as MethodCallExpression
Console.WriteLine ("The Method Is {0}", mce.Method.Name)
For (int I = 0; I < mce.Arguments.Count; iTunes +)
{
Analysis_Expression (mce.Arguments [I])
}
}
Break
Case ExpressionType.Quote:
{
UnaryExpression ue = exp as UnaryExpression
Analysis_Expression (ue.Operand)
}
Break
Case ExpressionType.Lambda:
{
LambdaExpression le = exp as LambdaExpression
Analysis_Expression (le.Body)
}
Break
Case ExpressionType.Equal:
{
BinaryExpression be = exp as BinaryExpression
Console.WriteLine ("The Method Is {0}", exp.NodeType.ToString ())
Analysis_Expression (be.Left)
Analysis_Expression (be.Right)
}
Break
Case ExpressionType.Constant:
{
ConstantExpression ce = exp as ConstantExpression
Console.WriteLine ("The Value Type Is {0}", ce.Value.ToString ())
}
Break
Case ExpressionType.Parameter:
{
ParameterExpression pe = exp as ParameterExpression
Console.WriteLine ("The Parameter Is {0}", pe.Name)
}
Break
Default:
{
Console.Write ("UnKnow")
}
Break
}
}
And call this method in CreateQuery
Of course, there must be parameters to call a method, so we also need to loop Arguments to analyze the specific parameters, including the object that calls the method. Naturally, we first analyze the object that calls the method. Here we make the first recursive call and jump to ExpressionType.Constant.
ExpressionType.Constant
NodeType is this type, so we can get the corresponding parameters through the ConstantExpression type. Through Value, we can get the object that calls the where method. Of course, we won't go any further at this point.
ExpressionType.Quote
People who have come into contact with lambda may think that the type should be Lambda, but they will not actually jump there directly, but first jump to Quote, and then we convert it to UnaryExpression type, and then continue to analyze the Operand attribute, and the NodeType of this property is Lambda. Personally, I think this should be a way to distinguish between lambda and normal, because where can not only receive lambda but also be a regular method, so this layer is also needed here.
ExpressionType.Lambda
Jump here, everyone will not feel strange, here for simplicity. The author does not analyze the parameters, but directly analyzes the Body part, because this part is the key to us.
At that time, I wondered why there was no such type, and I finally knew that I was playing this game. At this point, let's continue to analyze the parameters on the left and right sides of this equal operation.
When the parameters on the left are analyzed, we begin to analyze the parameters on the right.
ExpressionType.Constant
We can easily think that the corresponding Value is 123, and the whole expression is analyzed.
At this point, the study on "how to understand the IQueryable and IQueryProvider interfaces in Entity Framework" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.