3]. Main design models of the LINQ framework
At this point, we seem to be able to see the principle of LINQ. It is not an air garden, it has a foundation. With the support of a series of new features above, Microsoft builds a large-scale extension method to ensure that the above features can interact with each other and form a natural Integrated Query framework. The above features are all enhancements made by the language for the sake of LINQ. It can also be said that designers are constantly exploring new language features that are more in line with the modern development system, more and more functional programming features are supported. For example, the introduction of DLR provides powerful support for Python and Ruby functional scripting languages, and more functional scripting languages will be supported later.
Next we will mainly learn about object models. What is object models? In fact, most of the time we focus on language learning rather than focusing on the design principles of objects, leading to an increasing learning cost. We should learn and develop design capabilities more importantly (the so-called design capabilities reflect the technical level ). An object model is simply a design model of an object. How to construct a deep object structure that meets the needs. The design of the concept layer in the architecture system of the mainstream ORM framework ADO. NET EntityFramework on the. NET platform reflects the role of the object model. There are many object models worth exploring in the ADO. NET EntityFrameWork and Linq to SQL frameworks.
There are a lot of extension methods in the content of LINQ. There is actually a big design secret hidden behind these extension methods, that is, the chain programming model, next we will learn in detail the chained programming mode to understand why the same method can be consistently used by LINQ and how elegant it appears.[Wang qingpei has all rights reserved. For more information, please sign it.]
- 3. 1. Chain Design Mode (design system logic by pipeline-like link)
The chained design pattern is a kind of elegant pattern that has been ignored by us all the time. The last time I came into contact with it, the beauty of it was when I was learning LINQ, when I saw the continuous expansion method coming soon, I felt that this was really impeccable. In fact, in many cases, we can also use this design model to handle many difficult problems. The bold design is to use the chain mode to reorganize the fragmented business algorithms for human logic after the business is fragmented. If the design is good, it will be a top-level feast. As this article explains the content of LINQ, I will not talk about it much here. Later I will introduce a special article to explain the bold knowledge of chain business process reengineering.
In many cases, when designing a system function or application framework, we can use the chain design mode to elegantly develop our methods, making coding very smooth and convenient.
To express the use of chained design patterns in an image, I will use a simple example to demonstrate its design philosophy and usage.
Example: assume that I have a student object type and a student set type. The student set type is mainly used to hold student entities. The set type provides a series of methods to perform continuous operations on the set, which is commonly used for filtering. For example, to filter out all students whose gender is female, and then filter out the list of students older than 20 in the collection of all filtered female students, continue to filter student lists from Nanjing, Jiangsu province and so on. I think this processing method is the most common of LINQ. After all, it is generated for query, and the query is mainly for collection-class data.[Wang qingpei has all rights reserved. For more information, please sign it.]
Object graph:
650) this. width = 650; "border =" 0 "alt =" "src =" http://img1.51cto.com/attachment/201211/085136298.jpg "/>
In the object graph, we can clearly see the attributes and methods of each object. In the Student class, we define several basic Student attributes. The SelectByFemale method and SelectByMankind method are important in StudentCollection, which are the methods for screening female and male students respectively, in other words, SelectByAge and SelectByAddress are used to filter the age and address respectively. Since the specific method code is relatively simple, we will not post it here, so that you can intuitively see the benefits and flexibility of the chain design model.
Sample Code:
- // Construct the Student Array
- Student [] StudentArrary = new Student [3]
- {
- New Student () {Name = "Wang qingpei", Age = 24, Sex = "male", Address = "Nanjing, Jiangsu "},
- New Student () {Name = "Chen Yu and", Age = 23, Sex = "female", Address = "Yancheng, Jiangsu "},
- New Student () {Name = "Golden Source", Age = 22, Sex = "female", Address = "Huai 'an, Jiangsu "}
- };
- // Use the Student array to initialize the StudentCollection.
- StudentCollection = new StudentCollection (StudentArrary );
- StudentCollection WhereCollection =
- StudentCollection. SelectByFemale (). // filter out the list of all female students.
- SelectByAge (20). // filter out the list of students aged 20.
- SelectByAddress ("Nanjing, Jiangsu"); // lists the students whose addresses are "Nanjing, Jiangsu ".
Does it look very elegant? I think it is very elegant and comfortable. In fact, it may be awkward to design the methods inside the StudentCollection object, that is, each return type of the method must make the next method call smooth, therefore, you must ensure that each method call is of the same data type, that is, the StudentCollection type.
Many times our design thinking has blind spots, that is, it does not matter after each return, chained programming seems to have found this blind spot and seriously stressed the need to exercise this design blind spot on a regular basis. We use the Mind Map to analyze the blind spots of Chain Design, and also look for the design advantages that we often ignore.
Mind Map:
650) this. width = 650; "border =" 0 "alt =" "src =" http://www.bkjia.com/uploads/allimg/131228/1A3134436-1.jpg "/>
Each method in has a return type, but you only need to ensure that the returned type can be the operation object of the next method, when designing object methods, you must split the large process into a small process that can be organized. Many times it is hard to think about this when we design object models. In fact, we are not skilled enough. What we need to do is to practice more and read more design books. Leave the rest time.[Wang qingpei has all rights reserved. For more information, please sign it.]
- . Chained query method (process each work point in the query expression step by step)
In the above chain design model, we probably learned that if we build an object model that forms a loop, we can use the object set repeatedly to perform repeated query operations. In fact, this method is used by LINQ as its query principle. Here we will focus on the core design principles of LINQ. The LINQ chained model is mainly used to query object sets. By using a large-area build extension method, the object is filled with the query methods corresponding to the available LINQ expressions.
So how can we understand the query of LINQ? Most of the comrades know the syntax of LINQ, which is "from *** in *** where *** select ***" similar to SQL. In fact, this is a new query syntax built on CTS that is processed by the editor. It is not a C # Or a hosted language such as VB. NET. In fact, we all know that C #, VB. NET and other syntaxes are based on the. NET platform's IL intermediate language. They are part of the source code and are not the final output item of the program. IL is the program code of the output item after each compilation. In the end, the syntax of LINQ is also the syntax of IL. When we compile the query expression of LINQ, the editor has intelligently helped us translate the syntax into objects. Too many principles will be introduced in the next section.
The chain query method is also an object design problem. For details, refer to the chain design mode to naturally build a chain query method that meets our actual needs, the addition of these query methods has a major problem: they cannot be dynamically added to the objects to be extended. For example, you cannot directly modify published objects. Therefore, we use the extension method technology mentioned above, through the extension method, we can easily add actions for published objects. To be persuasive, let's look at a small column to strengthen our impression.[Wang qingpei has all rights reserved. For more information, please sign it.]
Example: assume that I have a set of simple ORM components that have been released. This component is built on. on top of NET2.0, now I need to extend it to a chained query method, instead of using the previously tedious query method. So I need to create a separate. NET3.0 or. as an Extension Assembly of the previous Assembly, NET3.5 can be used or not used. Only in this way can we use the extension method or other new syntax features.
- /// <Summary>
- /// Obtain the set of Base_Deptment Objects Based on the existing attributes in the Base_Deptment object.
- /// </Summary>
- /// <Param name = "model"> Base_Deptment instance </param>
- /// <Returns> Base_Deptment object instance set </returns>
- [ContextLogHandler (OperationSort = 1, OperationExtension = typeof (Dal. LogWrite)]
- Public List <Base_Deptment> GetAllListByPropertyValue (Base_Deptment model)
- {
- Return ORMHelper. FindEntityList <Base_Deptment> (model );
- }
ORMHelper. FindEntityList <T> is a generic method used to query the object list based on the existing attributes of an object. Of course, this is a simple demonstration. If I want to add other conditions, I must add values to the model parameter of the Base_Deptment type. Now I want to extend it to the chained query mode, for example:
- /// <Summary>
- /// Obtain the set of Base_Deptment Objects Based on the existing attributes in the Base_Deptment object.
- /// </Summary>
- /// <Param name = "model"> Base_Deptment instance </param>
- /// <Returns> Base_Deptment object instance set </returns>
- [ContextLogHandler (OperationSort = 1, OperationExtension = typeof (Dal. LogWrite)]
- Public List <Base_Deptment> GetAllListByPropertyValue (Base_Deptment model)
- {
- Base_Deptment QueryModel = new Base_Deptment ();
- Var selectList = QueryModel. Select (Base_Deptment Model) => Model. FiledObject. BDeptCode)
- . Where (Model) = & gt; Model. FiledObject. BDeptCode = "800103848 ")
- . OrderByAscending (Model) => model. FiledObject. BDeptCreateTime );
- Return selectList;
- }
-
The code here is only used in combination with context understanding. It may be unreasonable, but it has no impact.
In this way, you can design a very bloated function into such an elegant way of use. For the implementation of Linq to menmentity, I will discuss it in a special article later, so I won't go further here. The example itself is intended to tell us that we can use chained query for more user-friendly and elegant components or frameworks.[Wang qingpei has all rights reserved. For more information, please sign it.]
4]. Core Design Principles of the LINQ framework
- . Languages over managed languages (LINQ Query expressions)
Through the above example, we should have a basic understanding of the mysteries and application of the Chain Design Mode and chain query method. Through a simple example, we also realize that the chained query method has a unique advantage in data query, which is also a good way to understand LINQ.
So what does the chained query method provide for LINQ? Have you prepared the corresponding method? That's right. The chain design model provides a sufficient theoretical basis for chain queries, then, by constructing a chain query method in a large area and matching the query operator of the LINQ query expression, it naturally becomes a good link to query any data source using LINQ. LINQ provides a unified query interface, and then uses a custom chained query method to form a Lambda expression for user operation data, then, extract the relevant data structure in the Lambda expression to organize the parameters you want to send to the data driver for data query.
As a convenience syntax supported by the editor, LINQ does not fall into the category of hosting languages. It aims to reduce the trouble of directly using the query method. In contrast, if we directly use the query method, we will spend a lot of energy and time.
Sample Code:
- // Construct the Student Array
- Student [] StudentArrary = new Student [3]
- {
- New Student () {Name = "Wang qingpei", Age = 24, Sex = "male", Address = "Nanjing, Jiangsu "},
- New Student () {Name = "Chen Yu and", Age = 23, Sex = "female", Address = "Yancheng, Jiangsu "},
- New Student () {Name = "Golden Source", Age = 22, Sex = "female", Address = "Huai 'an, Jiangsu "}
- };
-
- Var list = StudentArrary. Where (studentModel) => studentModel. Name = "Wang qingpei"). Select (studentModel) => studentModel );
- Var list = from I in StudentArrary where I. Name = "Wang qingpei" select I;
-
There are two ways to query the set data. The first is to query the data using the chain query method. The second is to query data using a LINQ query expression. There is no doubt that it is convenient to use LINQ, which is simple and more suitable for the SQL query method we are used.
In this way, we can easily obtain a filtered object. The editor is responsible for processing LINQ, rather than CLR, and processing LINQ into the basic interface set implemented by the framework. Remember, LINQ is at the syntactic sugar level. It is not supported by C #, VB. NET, or the basic kernel of CLR.[Wang qingpei has all rights reserved. For more information, please sign it.]
- . Basis of managed language structure (connection between generic interfaces and query operators in LINQ)
As a unified data query interface, how does one directly connect to different data sources? In summary 4.1, we found the specified items in the Student [] array through a simple LINQ query expression. How does this work? Next we will take a step-by-step analysis on how to implement unified data query in LINQ.
Now let's assume there is no LINQ. Let's see how. NET builds an internal library that supports LINQ.
In. introduced in NET3.5, the core assembly is System. core. dll. There are two namespaces that are directly related to LINQ, namely System. (the method set of the chained query directly corresponding to the Linq query expression), System. linq. expressions (logical expression tree in the LINQ query expression ). In System. Linq, the primary class is the Enumerable static class, which encapsulates the static Extension Method for querying the IEnumerable interface type. Note that the data sources to be queried by LINQ are mainly divided into two types. The first and foremost supported data sources must be Linq to object. For objects in the memory, the query is based on IEnumerable objects, the query is for collection classes. NET uses IEnumerable as the implementation interface of the iterator object. linq. all the static Enumerable classes encapsulate the chain query methods for the IEnumerable interface. These methods are provided through the extension method, that is, in. versions earlier than NET3.5 are not available, and the extended assembly package will not be loaded. More importantly, all the logical expressions in the extension method are Func generic delegates, that is, they are directly used to execute logical operations, we provide logical conditions in the form of Lambda when calling. These logics are directly compiled into executable anonymous methods, rather than Expression object expressions, you can directly call the query of objects in the memory.
Another kind of query objects supported by LINQ are our custom data sources. The query Chain Method of these data sources is System. linq. provided by the Queryable class, if we use a LINQ query expression to query the System. linq. IQueryable <T> type object, the editor will think that you are querying the custom data source object, and will call your System during execution. linq. IQueryableProvider <T> interface implementation class. This class parses and executes the Expression Tree. Take a closer look at System. linq. all extension methods in the Queryable static class and System. linq. the difference between the extension methods in the Enumerable class is that all Func types are System. linq. expressions. expression <T> type is encapsulated, which also conforms to what we mentioned in the previous article. linq. expressions. expression Parsing is used as a data structure. When necessary, we can read the relevant logical structure by ourselves.
Whether it is to query Linq to object or a custom data source, the query's LINQ syntax remains unchanged. This means that the data query interface is unified and the Data Query provider needs to be changed, both Linq to SQL and Linq to Entities implement the Custom Data Source Query function.[Wang qingpei has all rights reserved. For more information, please sign it.]
- . Go deep into IEnumerable, IEnumerable <T>, and Enumerable (the entrance of the LINQ to Object Framework)
The 4.2 clause has already supported the LINQ query. What is the difference between the query and the query? What is the difference between IEnumerable and IQueryable? How to understand the relationship between the two in the overall framework of LINQ.
As a unified data query interface on the. NET platform, we can query data of any type or in the online world. Therefore, no matter what data we want to query, we need to create a mature object model. If we still directly drag the data from the server and then use a DataTable or DOM tree, in fact, it is of little significance. We need to be able to continuously query objects in the memory. When we query data from the remote server to the memory, we need to use the object model we created to visualize it to prepare for the Linq to object. Only Linq to object can be perfectly executed with Linq to custom. This is a reverse relation.
The generic IEnumerable <T> interface inherits from the IEnumerable interface, which represents a set of data that can be iterated. Linq to object is the set to query IEnumerable <T>. All static methods in the Enumerable static class correspond to the LINQ query expression that operates the IEnumerable <T> set. When each query is performed, the static methods in the Enumerable class are directly called. There is actually not much to talk about for the Linq to object. The only thing to do is to familiarize yourself with the query expression syntax of the LINQ.
- 4. go deep into IQueryable, IQueryable <T>, and Queryable (entrance to the LINQ to Provider Framework)
The IQueryable interface is provided for us to implement custom data sources. To support strong data source sets, we directly use the IQueryable <T> interface, when we use LINQ to query the IQueryable <T> interface, the query expression is directly compiled into the corresponding static Extension Method in the corresponding Queryable static class. Logical conditions are processed as Query expressions, rather than the IEnumerable <T> interface. Of course, it is still difficult to implement the data source query by ourselves. We need to process the expression directory tree on our own. The subsequent articles will explain in detail.[Wang qingpei has all rights reserved. For more information, please sign it.]
- 4.5.LINQ Query Interfaces for different data sources
So far, I think we have a general understanding of the Unified Data Source Query of LINQ. No matter what the data source is, RDMS, DOM, and so on, we have a corresponding query method, the hard work is just encapsulation of people. Friends who are working in the background development may need to use these special query languages to query data, so that the front-end programmers can easily use the LINQ to query data sources.
The primary task of component developers is to create an object model. This object model should be an abstract model of the real data source, so that the object may be successfully put into IQueryable for query.
- . Summarize the overall principles of the LINQ framework
Through the above detailed introduction, we have a basic understanding of the LINQ framework. If you just use it, it is actually very simple, as long as you are familiar with the query syntax of LINQ, however, I think every programmer has a strong curiosity and wants to understand the design principles of the framework. This is what we must do.
The final result of the LINQ query expression is the called chained query method. These methods are defined in static classes. The IEnumerable <T> type is directly called and executed using an anonymous method, IQueryable <T> is performed manually, that is, the custom data source. Some lightweight query libraries, such as Linq to xml, Linq to SQL, and Linq to Entities, are examples of excellent extended data sources. It is worth exploring and learning.[Wang qingpei has all rights reserved. For more information, please sign it.]
This article is from the pattern driven the world blog, please be sure to keep this source http://wangqingpei557.blog.51cto.com/1009349/1068009