1. Trang chủ
  2. » Công Nghệ Thông Tin

Hướng dẫn học Microsoft SQL Server 2008 part 83 pptx

10 122 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 515,11 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Whereas the LINQ query and the T-SQL query are executed similarly, the T-SQL query syntax is a bit different.. In the next example, the LINQ query uses the same syntax to query data from

Trang 1

(4) WHERE (5) GROUP BY (6) WITH (7) HAVING (10) ORDER BY

Notice that theFROMclause is processed first, while theSELECTclause is processed almost last Any

clause that is not specified in the query is simply skipped by the query processing engine This

informa-tion is important because it points out the similarities between LINQ query syntax and how SQL Server

processes a query

For more information on SQL logical query flow, please see Chapter 8, ‘‘Introducing Basic Query Flow.’’

In a LINQ query, the first clause is theFROMclause, which specifies the source of the data, and it must

end with either aSELECTclause or aGROUPclause The first clause, called a generator, defines where

the data will be coming from when the query is executed It also specifies the range variable that is used

as a reference for each element in the data source For example, the following uses LINQ to return a list

of the directories in the root of a hard drive:

DirectoryInfo di = new DirectoryINfo("C:\\");

var query =

from dir in di.GetDirectories() order by di.Name

select new { dir.Name };

foreach (var item in query) Console.WriteLine(item.Name);

In this example, the first statement creates a new instance of theDirectoryInfoclass This is what is

used to retrieve a list of the directories

The second statement is the LINQ statement The variablevaris the query variable This variable does

not store actual result data The results are produced during the iteration of the query, which is done in

theforeachloop When theforeachstatement executes, the query results are returned during each

iteration in the variable item

Whereas the LINQ query and the T-SQL query are executed similarly, the T-SQL query syntax is a bit

different In T-SQL, the query would be executed internally following the steps described earlier With

LINQ, the query does not need to go through the rewriting process

In the next example, the LINQ query uses the same syntax to query data from theContacttable in the

AdventureWorksdatabase in SQL Server:

var query = from c in Contact where c.FirstName.StartsWith("S") orderby c.LastName

select c;

Trang 2

Notice in this query that the syntax is exactly the same as the first query An additionalWHEREclause

has been added, but syntactically it is the same This is what is great about LINQ Similar query

expres-sions can be written against two completely different sources of data

Query syntax and method syntax

LINQ has the ability to write queries using both query syntax and method syntax The examples shown

so far have used query syntax, which is writing the query as a query expression, as follows:

IEnumberable<string> query =

from c in Contact

where c.FirstName.StartsWith("S")

select c;

This declarative syntax is easy to read and understand, but developers also have the option of writing

queries using method syntax When a LINQ query is compiled, the query expression is translated into

method syntax because the NET CLR (common language runtime) doesn’t understand query syntax

Thus, at compile time, query expressions are translated into method calls because this is what the CLR

understands

The following shows the previous query written using method syntax:

IEnumberable<string> query = contact.Where(c =>

c.FirstName.StartsWith("S"));

For clarification, take a look at a couple more examples This first example adds an additional filter to

the previous example:

IEnumberable<string> query =

from c in Contact

where c.FirstName.StartsWith("S")

&& c.LastName.StartsWith("A")

select c;

Here is the same query in method syntax:

IEnumberable<string> query = contact.Where(a =>

a.FirstName.StartsWith("S") && a.LastName.StartsWith("A"));

Just to complicate things a bit more, this next example adds anOrderByclause:

IEnumberable<string> query =

from c in Contact

where c.FirstName.StartsWith("S")

&& c.LastName.StartsWith("A")

order by c.LastName

select c;

Trang 3

The preceding query written using method syntax is as follows:

IEnumberable<string> query = contact.Where(c =>

c.FirstName.StartsWith("S") && c.LastName.StartsWith("A")) OrderBy(c => c.LastName);

The output of both queries is identical

Choosing a query syntax

As you have seen, although there are syntactical differences between query syntax and method syntax,

execution is essentially the same However, the NET CLR does not understand query syntax, so it is

translated into method syntax anyway The CLR understands method calls, so query expressions are

translated into method syntax (method calls) and executed as such

Although there is no semantic difference between method syntax and query syntax, I recommended that

developers use query syntax whenever possible, as it is easier to read, understand, and maintain

Now that you have a good understanding of LINQ, the standard query operators, and LINQ query

expressions, the rest of this chapter focuses on the LINQ providers and offers detailed examples of each,

beginning with LINQ to SQL

LINQ to SQL

LINQ to SQL is part of ADO.NET which provides a run-time infrastructure for mapping relational data

as objects In essence, it is an ORM (object-relational mapping) framework that enables the direct 1-to-1

mapping of a SQL Server database and its objects to NET classes without losing the ability to query

One of most important things that developers need to understand when working with LINQ to SQL is

theDataContextclass TheDataContextis the main medium through which objects are retrieved

from the database and changes are resubmitted TheDataContextis much like an ADO.NET

connec-tion in that it is initialized with a connecconnec-tion string

TheDataContexthas the responsibility of converting objects, which means that because LINQ to SQL

deals with objects, theDataContextconverts the objects into SQL queries, as well as reassembling the

results back into queryable objects

TheDataContexthas several overloads, one of which is just a simple connection string specifying the

connection information, as shown here:

DataContext db = new DataContext("Initial Catalog=AdventureWorks; i Integrated Security=sspi");

It is recommended, however, that you use strongly typedDataContexts This is as simple as creating

a new class that inherits from theDataContextclass:

[Database(Name = "AdventureWorks")]

public class AdventureWorks : DataContext {

public AdventureWorks(string connection) : base(connection) {}

}

Trang 4

Here, the strongly typedDataContextis given the same name as the database to use — in this case,

theAdventureWorks(2005 and 2008) database Therefore, no database needs to be specified in the

connection string

In the preceding example, the[Database]attribute is applied to any strongly typedDataContext

declaration This attribute is optional, but when it is used aNameproperty must also be used to

sup-ply the name of the database to which you are mapping This attribute maps the database in theName

property to your entity class

With theDataContextcreated, the next step is to create mappings to the specific objects Database

tables are represented by entity classes in LINQ to SQL An entity class is a normal class annotated with

a specific tag that maps that class to a specific table in the database

TheTableattribute, part of theSystem.Data.Linq.Mappingnamespace, maps an entity class to a

database table or view This attribute has a single property,Name, which specifies the name of the

rela-tional table or view

In the following example, theTableattribute is applied to a class to define a mapping between the

Person.Contacttable in the AdventureWorks database and a class namedContact:

[Table(Name="Person.Contact")]

public class Contact

{

//

}

Once the table is mapped to an entity class, table columns must be mapped to class properties This is

accomplished by applying theColumnattribute, which maps a database table column to a member of

an entity class, as shown here:

[Column(DbType="nvarchar(50) not null")]

public string FirstName

Several properties are commonly applied with this attribute, including the following:

■ Name: The name of the table column

■ DbType: Database type of the column

■ IsPrimaryKey: Specifies that the associated column is the primary key of the corresponding

table

■ IsDbGenerated: Specifies that the associated column auto-generates its values

■ CanBeNull: Specifies that the associated column can contain null values

So far, the connection has been defined via theDataContext, and the table and column mappings

have been defined When this is all put together, it looks like the following:

public class AdventureWorks : DataContext

{

public AdventureWorks(string connection) : base(connection) {}

public Table<Contact> Contact;

}

Trang 5

public class Contact {

[Column(DbType="nvarchar(50) not null")]

public string FirstName }

To help this sink in, this section offers a couple of examples The first example applies the mappings

manually, and the second example illustrates an easier way

Example 1: Manually applying the mappings

For this first example, follow these steps:

1 Create a new Visual Studio C# Windows project.

2 Add a reference to theSystem.Data.Linqcomponent

3 On the form, add a button and a list box.

4 Add a new class to the project and name itAdventureWorks

5 Open the new class and replace all the code that is there with the following code (Because

I named my project LINQ, the namespace is called LINQ Be sure to change the namespace name if you named your project something different.)

using System.Data.Linq;

using System.Data.Linq.Mapping;

using System.Data;

using System.Collections.Generic;

using System.Reflection;

using System.Linq;

using System.Linq.Expressions;

using System.ComponentModel;

using System;

namespace LINQ {

[Database(Name = "AdventureWorks")]

public class AdventureWorks : DataContext {

public AdventureWorks(string connection) : base(connection) {

} public Table<Contacts> Contact;

} [Table(Name="Person.Contact")]

public class Contacts {

[Column(DbType = "int not null", IsDbGenerated = true, IsPrimaryKey = true)]

Trang 6

public int ContactID;

[Column(DbType = "nvarchar(8)")]

public string Title;

[Column(DbType = "nvarchar(50)")]

public string FirstName;

[Column(DbType = "nvarchar(50)")]

public string MiddleName;

[Column(DbType = "nvarchar(50)")]

public string LastName;

[Column(DbType = "nvarchar(50)")]

public string EmailAddress;

[Column(DbType = "int")]

public int EmailPromotion;

[Column(DbType = "bit")]

public byte NameStyle;

}

}

This code first defines theDataContextclass The next section of code defines a class that

maps that class to thePerson.Contacttable (in SQL Server 2005) as well as maps several

columns from the table to members of the class

Note some of the properties used in theColumnattribute applied to theContactID

mem-ber TheContactIDcolumn in thePerson.Contacttable is a primary key column that

auto-generates its IDs Thus, in order for LINQ to support this and recognize this functionality,

theIsDbGeneratedandIsPrimaryKeyproperties need to be used

6 In the Click event of the button on the form, add the following code:

AdventureWorks db = new AdventureWorks("Data Source=ServerName;

Initial Catalog=AdventureWorks;Integrated Security=sspi");

var query = from con in db.Contact where con.FirstName.StartsWith("S") select con;

foreach (var cont in query) listBox1.Items.Add(cont.FirstName);

7 Compile the project to ensure that there are no errors, and then run it When the form

dis-plays, press the button The list box should be populated with the first name of all contacts

whose first name begins with the letter S

Prior to moving on to the next example, let’s take a closer look at this one The class created earlier

used LINQ to SQL to define the mapping between the relational data and the class On the form, an

Trang 7

instance of the class was created, and a LINQ query was created and used, employing a few of the

standard query operators The query was then iterated over, at which point the data was returned to the

application

The thing to pay attention to here is the query itself As the query was typed, IntelliSense displayed the

column names of the table, as well as a list of the available standard query operators and methods This

is LINQ in all its glory! Equally, notice that the syntax used to retrieve relational data is exactly the same

as what was used to query the directories on the local drive in the example shown earlier

This first example demonstrated how to create the mapping classes manually in order to provide a good

understanding of how the mapping works However, there is an easier way

Example 2: The easy way

For this second example, follow these steps:

1 In Visual Studio, right-click the project in the Solution Explorer and select Add➪ New Item

2 When the Add New Item dialog appears, select the LINQ to SQL Classes item from the list of

templates Name itAWDB.dbmland click OK

A LINQ to SQL designer page will open in the Visual Studio environment This object-relational designer provides a visual surface for creating LINQ to SQL entity classes and rela-tionships based on database objects In essence, this is where the object model is defined that maps database objects within an application

3 The empty design surface represents aDataContextthat is ready to be configured From here, open the Server Explorer and, if necessary, create a connection to the AdventureWorks database Once that is created, database objects can be dragged onto the designer

4 For this example, drag thePerson.Contacttable onto the designer and then save the project Next, modify the code behind the button on the form to look like the following:

AWDBDataContext db = new AWDBDataContext();

var query = from con in db.Contacts where con.FirstName.StartsWith("S") select con;

foreach (var cont in query) listBox1.Items.Add(cont.FirstName);

The only thing that changes is the first line; everything else remains the same Run the project and click the button The list box will be populated with the same data presented in the first example

5 Before moving on, however, a few things need to be highlighted In the Solution Explorer,

expand the AWDB node Underneath that node are two files:AWDB.dbml.layoutand

AWDB.designer.cs The layout file simply contains the layout information for the designer If you open this file you will see that it is simply an XML file

The important file is thedesigner.csfile Open this file and notice that it looks very similar

to the file manually created in the first example It contains a bit more information than the one you manually created earlier, but overall it is the same

Trang 8

One of the differences between the two examples is that connection string information needed to be

passed in the first example, whereas no connection information needed to be passed in the second

example This is because the Server Explorer connection information was automatically saved and

added to the project’s resource file when the OR mapping was created In thedesigner.csfile, the

DataContextclass contains the following:

public AWDBDataContext() :

base(global::LINQ.Properties.Settings.Default AdventureWorksConnectionString, mappingSource)

{

OnCreated();

}

Right-click on the lineAdventureWorksConnectionStringand select Go To Definition, which

will take you to where the connection string is defined in the project settings Notice that the

AWDBDataContexthas several overloads, which enables different connection information to be passed

to theDataContext

Much more could be said about LINQ to SQL, but this should provide a solid foundation for

under-standing how it works Your homework assignment for this section is to add more tables to the

designer, look at their relationships, and modify the LINQ query to utilize the relationships (hint: use

theJOINoperator)

LINQ to SQL and Stored Procedures

Afew words on using LINQ to SQL and stored procedures I am a firm believer in using stored procedures

for several reasons:

■ They provide a layer of abstraction

■ They provide increased maintainability

■ They enable performance improvement through database query optimizations

The great thing about LINQ is that it supports accessing data by calling and executing stored procedures For

example, given the following stored procedure:

CREATE PROCEDURE [dbo].[uspGetSalesOrderDetail]

@SalesOrderID [int]

AS

BEGIN

SET NOCOUNT ON;

SELECT SalesOrderDetailID,

OrderQty,

continued

Trang 9

ProductID,

UnitPrice,

LineTotal

FROM Sales.SalesOrderDetail

WHERE SalesOrderID = @SalesOrderID

END;

Calling a stored procedure is as simple as the following:

var query = db.uspGetSalesOrderDetail(43659)

foreach (SalesOrderDetailResult salesOrderDetail in query)

{

//do something }

However, while using stored procedures does have its advantages, it is still an individual call as to when and

where stored procedures are appropriate For example, if I know that a query will always return a single row

(and maybe only few columns), then I may forgo using a stored procedure in that case If I have a complex

T-SQL query, then I will more than likely use a stored procedure

My recommendation is to experiment and find what works best given the scenario in your application Using

stored procedures provides certain benefits, such as those listed earlier, but not all scenarios need stored

procedures; and as you become familiar with LINQ and LINQ to SQL, you will find what works best in each

situation

LINQ to XML

I love XML The fact that it is entirely possible to query XML using LINQ just rocks my world It

is an excellent form of moving and storing data Those who have used other technologies to query

XML know that it can be somewhat difficult and cumbersome LINQ to XML is heaven sent This

section introduces LINQ to XML and demonstrates how easy it is to create and query XML using LINQ

to XML

The component that gives LINQ to XML its power is theSystem.Xml.Linqnamespace, and

its corresponding classes These classes provide the capability to work with XML with ease,

leav-ing behind the need to work with complex and cumbersome technologies such as the DOM and

XQuery

Table 34-2 describes the 19 classes contained in theSystem.Xml.Linqnamespace that enable

devel-opers to easily work with XML

Trang 10

TABLE 34-2

LINQ to XML Classes

XAttribute Represents an XML attribute

XCData Represents a CDATA text node

XComment Represents an XML comment

XContainer An abstract base class representing nodes that have child

nodes XDeclaration Represents an XML declaration

XDocument Represents an XML document

XDocumentType Represents an XML DTD

XElement Represents an XML element

XName Represents the name of an XML element or attribute

Xnamespace Represents an XML namespace

XNode An abstract class representing nodes of an XML element

tree XNodeDocumentOrderComparer Provides mechanisms for node comparisons regarding

their order within the XML document XNodeEqualityComparer Provides mechanisms for node comparisons regarding

their equality value XObject An abstract class representing XNodes and XAttributes

XObjectChange The event type when an XObject event is raised

XObjectChangeEventArgs Provides information and data for the Changing and

Changed events XObjectChangeEventHandler The method that handles the XObject’s Changed and

Changing events XProcessingInstruction Represents an XML processing instruction

Ngày đăng: 04/07/2014, 09:20

TỪ KHÓA LIÊN QUAN