In the previous chapter, we learned a few features related to LINQ. In the next two chapters, we will learn how to use LINQ to query a database, or in other words, how to use LINQ to Entities in C#. After reading these two chapters, we will have a good understanding of LINQ to Entities so that we can rewrite the data access layer of our WCF Service with LINQ to Entities, to securely and reliably communicate with the underlying database.
In this chapter, we will cover the basic concepts and features of LINQ to Entities:
Northwind
database with LINQ to EntitiesIn the next chapter, we will cover the advanced concepts and features of LINQ to Entities such as stored procedure support, inheritance, simultaneous updating, and transaction processing.
LINQ to Entities is considered to be Microsoft's preferred ORM product. So before we start learning LINQ to Entities, let's first understand what an ORM is.
ORM stands for Object-Relational Mapping. Sometimes it is called O/RM or O/R mapping. It is a programming technique that contains a set of classes that map relational database entities to objects in a specific programming language.
Initially, applications could call specified, native database APIs to communicate with a database. For example, Oracle Pro*C
is a set of APIs supplied by Oracle to query, insert, update, or delete records in an Oracle database from the C applications. The Pro*C
pre-compiler translates embedded SQL into calls to the Oracle runtime library (SQLLIB
).
Then ODBC (Open Database Connectivity) was developed to unify all of the communication protocols for various relational database management systems (RDBMS). ODBC was designed to be independent of programming languages, database systems, and operating systems. So with ODBC, one application can communicate with different RDBMS by using the same code simply by replacing the underlying ODBC drivers.
No matter which method is used to connect to a database, the data returned from a database has to be presented in some format in the application. For example, if an Order
record is returned from the database, there has to be a variable to hold the Order
number and a set of variables to hold the Order
details. Alternatively, the application may create a class for Orders
and another class for Order
details. When another application is developed, the same set of classes may have to be created again, or, if it is designed well, they can be put into a library and re-used by various applications.
This is exactly where an ORM fits in. With an ORM, each database is represented by an ORM context object in the specific programming language and database entities such as tables are represented by classes with relationships between these classes. For example, an ORM may create an Order
class to represent the Order
table and an OrderDetail
class to represent the Order Details
table. The Order
class will contain a collection member to hold all of its details. The ORM is responsible for the mappings and the connections between these classes and the database. So to the application, the database is now fully represented by these classes. The application only needs to deal with these classes, instead of with the physical database. The application does not need to worry about how to connect to the database, how to construct the SQL statements, how to use the proper locking mechanism to ensure concurrency, or how to handle distributed transactions. These database-related activities are handled by the ORM.