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

Microsoft SQL Server 2008 R2 Unleashed- P185 docx

10 193 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 362,44 KB

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

Nội dung

LISTING 45.2 Your First LINQ to SQL Query public List GetProductsByIdint ProductId { AdventureWorks2008DataContext Context = new AdventureWorks2008DataContext; var query = from p in Cont

Trang 1

FIGURE 45.3 Adding a LINQ to SQL classes file to your Windows Forms sample application

After your new .dbmlfile is created in your project, Visual Studio’s Object/Relational (O/R)

Designer opens up with its blank surface ready On this surface, you add C# data classes

that mirror the tables and relationships in your database This is the heart of what is

known as object/relational mapping (ORM): each class represents a database table Each

instance of that class represents a row in that table Each property on each instance

repre-sents either a column and its value, or a collection of related (via ORM) objects Changes

to these object instances (including updates, insertions, and deletions) once committed,

are reflected as changes to the underlying rows in your tables LINQ to SQL operates on

these ORM objects, which are defined in the code of your .dbmlfile

Using Visual Studio’s View menu, open Server Explorer Right-click its root node and select

Add Connection Fill out the form to set up a connection to your AdventureWorks2008

database When done, navigate to that new node in Server Explorer (it is named

[ServerName]\[InstanceName].AdventureWorks2008.[SchemaName]) (This new node

should have a tiny image of a plug on its icon.) Expand this node and then expand the

Tablesnode to view the tables in your database

Shift-click the following table nodes in Server Explorer and then drag them all to your O/R

Designer surface and release the mouse button (answer Yes to the ensuing warning dialog):

Product (Production)

ProductModel (Production)

ProductInventory (Production)

ProductReview (Production)

Your O/R Designer surface should now look something like the one in Figure 45.4

The best way to introduce any new technology is with sample code, so let’s jump right in

and write a LINQ to SQL query

Trang 2

FIGURE 45.4 Viewing Visual Studio’s O/R Designer surface for the Windows Forms sample

application

Right-click your Windows Forms project in Solution Explorer and then click Add Class

Name your new class LINQExamples.csand then add the code from Listing 45.2 into its

body

LISTING 45.2 Your First LINQ to SQL Query

public List<Product> GetProductsById(int ProductId)

{

AdventureWorks2008DataContext Context =

new AdventureWorks2008DataContext();

var query =

from p in Context.Products

where p.ProductID == ProductId

select p;

return query.ToList();

}

Trang 3

Going Deeper

LINQ requires an understanding of generics (introduced in NET 2.0), which provide a

means of working with classes in a type-independent manner That is, a generic class

provides methods and properties just like any other class; however, it also has a type

para-meter that enables users of that class to supply a type at runtime that the algorithms in

the class will then operate on In Listing 45.2, for example, the return type of

GetProductsByIduses the generic Framework class System.Collections.Generic.List<T>,

substitutingProductas a type parameter for T

When working with LINQ to SQL, you also use the new varkeyword, which indicates that

the named variable is implicitly typed This means that the compiler will infer the type of

the statement on the right by walking down the expression at compile time In many

cases, your LINQ statements end up being implicitly typed as

System.Linq.IQueryable<T> This generic class stores the abstract expression tree that will

be translated (at execution time) to T-SQL, information about the query provider (in this

case SQL Server), as well as the enumerable collection itself that provides access to the

data the query returns

IQueryable<T>itself derives from System.Collections.Generic.IEnumerable<T>.One

reason for this is that, under the hood, the compiler converts the query syntax used in

Listing 45.2 to actually use generic query operators defined as extension methods to

IEnumerable<T>, including Select,Where,OrderBy,Distinct, and so on (Extension

methods provide a means of adding methods to classes that are otherwise sealed, that is,

noninheritable) This means that the query in Listing 45.2 could also have been written as

var query = Context.Products.Where(p => p.ProductID == ProductId);

Because of their common return type (IEnumerable<T>), LINQ’s extension methods may

be chained together For example:

var query =

Context.Products.Where(p => p.ProductID == ProductId).OrderBy(p =>

p.ProductID).Distinct();

The parameter to the WhereandOrderBymethods shown here is built on another new

construct called a lambda expression, which is an anonymous function that can be cast to a

delegate (such as System.Func<T, TResult>, the delegate type required by the input

para-meter to the extension method Where) Lambda expressions take the form input

parame-ters => expression, where the lambda operator=>is read as “goes to.” (For more

information, refer to the MSDN article titled “Lambda Expressions.”) Put simply, these

expressions provide a compact syntax for writing anonymous functions that you will use

more often as you progress deeper in your knowledge of LINQ For now, let’s get back to

the code in Listing 45.2

First, in the method signature, you can see that GetProductsByIdtakes an integral

ProductIdas input and returns a generic ListofProductobjects What is a Product

Trang 4

object? It’s a LINQ to SQL class instance that points (is object/relationally mapped) to a

particular row in the Production.Producttable

You can think of a Productobject as an “objectified” SQL Server row, insofar as its

primi-tively typed properties are akin to SQL Server column values It also has collection-backed

properties that point to rows stored in the tables to which it is related These specialized

LINQ collections are of type System.Data.Linq.EntitySet Let’s examine theclass

defini-tion of Productto see how this plays out

Using Solution Explorer, expand the AdventureWorks2008.dbmlfile to reveal

AdventureWorks2008.designer.cs This code file contains all the ORM logic needed to use

LINQ to SQL with your database Double-click this file and, using the drop-down at the

top left of your code editor window, select [YourProjectName].Product.

Above your class’s name, notice the Tableattribute (attributes are NET classes used to

decorate other classes with information queryable at runtime) Its Nameproperty reveals

that the class it decorates is to be mapped to rows in Production.Product As you scroll

down, examine this class a bit more Notice how its primitive properties map nicely to the

columns of your table Notice also how each property has its own Columnattribute,

signi-fying the specific SQL Server column to which it is mapped

As we mentioned earlier, the Productclass also has collection-backed properties, such as

ProductInventoriesandProductReviews These properties represent the tables related

(via primary and foreign keys) to Product By using properties in your NET code, you can

navigate from a parent object in Productto a child object in ProductInventories, just like

you would when writing T-SQL joins Not surprisingly, each Associationattribute found

on your collection-backed properties denotes the direction of the navigational path from

parent to child

The glue that holds all this together is theSystem.Linq.DataContextclass, represented in

Listing 45.2 by yourContextobject (which is of typeAdventureWorks2008DataContext) Put

simply,DataContextis the ORM bridge or conduit from NET to SQL Server and back

At the top of your designer file, you can see that the DBML class inherits from

System.Data.Linq.DataContext Notice its mapping attribute, Database, which indicates

that it is mapped to AdventureWorks2008 As the SQL Server conduit, you use the

DataContextinstance to select your object-mapped rows Through it, you commit inserts,

updates, and deletes to the underlying tables, by adding, changing properties of, and

removing objects from its System.Data.Linq.Tablecollection’s properties These

collec-tions represent the tables you added to your O/R Designer’s surface And this is the real

power of LINQ to SQL: no longer is it necessary to waste hours writing boilerplate T-SQL

to perform simple database operations; you can get it all done with pure NET code

Let’s look at a slightly more complex LINQ query that leverages the power of key-based

rela-tionships to select related database objects In Listing 45.3, you add a new method to the

sample class that gets aListofProductReviewobjects for a givenProduct

Trang 5

LISTING 45.3 Using Database Relationships to Select Related Objects with LINQ to SQL

public List<ProductReview>

GetProductReviewsByProduct(Product MyProduct)

{

AdventureWorks2008DataContext Context =

new AdventureWorks2008DataContext();

var query =

from p in Context.Products

join r in Context.ProductReviews

on p.ProductID equals r.ProductID

where p.ProductID == MyProduct.ProductId

select r;

return query.ToList();

}

Notice the joinsyntax introduced in this example As you can see, it’s a lot like T-SQL’s

INNER JOIN, and it performs the same basic function The whereclause in the example is

also just like T-SQL’s WHERE, except for the fact that you have to use C#’s ==operator

instead of T-SQL’s =) The one big difference to pay attention to is that with LINQ your

selectstatement comes last, and your fromclause comes first Remember that all the

tables you want to select from are properties (System.Data.Linq.Tableobjects) of the

DataContextobject Very simple, very powerful

Uncovering LINQ to SQL with Linqpad

You may be curious about the T-SQL that LINQ is generating for this NET expression To

reveal this mystery, you can use two tools: SQL Server Profiler and Linqpad To use

Profiler, launch the application from the Windows Start menu, create a new trace using

the File menu (select New Trace), and connect to your database of choice On the ensuing

Trace Properties dialog, select the trace template called T-SQL_SPs, start the trace, and then

run the LINQ statement found in Listing 45.3 The T-SQL that LINQ generates is revealed

in the TextDatacolumn

Alternatively, you can download and use the amazing Linqpad from http://www.linqpad

net Visit the site and download Linqpad.exe Save it to a folder that you will remember

As of this writing (version 1.35), Linqpad does not have or need an installation program;

the download itself is the entire self-contained application

After you download Linqpad, start it Click on the Add Connection link at top left of the

application’s main window; then add a connection to your local server Next, select the

AdventureWorks2008database using the drop-down at the top left In the query window,

Trang 6

type the following LINQ statement (Hint: This is the same as shown in Listing 45.3, minus

the method signature, input parameter, and Contextobject):

from p in Products

join r in ProductReviews

on p.ProductID equals r.ProductID

select r

Click the green arrow button or press F5 Your query results show up in a visually friendly

tabular format in the results area below the query window Notice just above the results

area there is a button bar with four buttons: Results, Δ; (lambda expression), SQL, and IL.

You’ve seen what shows up with the default setting, Results.Δ; reveals the underlying

anonymous functions upon which LINQ relies IL shows you the CLR Intermediate

Language code that your LINQ expression generates Finally, SQL shows the resultant

T-SQL, of main concern to you now Select SQL and press F5 again Your results should

match the code shown in Figure 45.5 You can also use the Analyze SQL menu option

(above the results area) to jump into SSMS to run your query, or you can even run the

T-SQL itself via Linqpad

Next, let’s examine an insert query using LINQ to SQL, as shown in Listing 45.4

FIGURE 45.5 Viewing the T-SQL Generated by a LINQ Query with Linqpad

Trang 7

LISTING 45.4 An Insert Query Using LINQ to SQL

public void AddProductReview(

int ForProductId,

string Comments,

string Email,

int Rating,

string Reviewer

)

{

AdventureWorks2008DataContext Context =

new AdventureWorks2008DataContext();

ProductReview NewReview =

new ProductReview()

{

Comments = Comments,

EmailAddress = Email,

ModifiedDate = DateTime.Now,

ProductID = ForProductId,

Rating = Rating,

ReviewDate = DateTime.Now,

ReviewerName = Reviewer

};

Context.ProductReviews.InsertOnSubmit(NewReview);

Context.SubmitChanges();

//Check the new review ID:

if (NewReview.ProductReviewID > 0)

{

Debug.WriteLine(

string.Format(

“Success! Added new ProductReview with ID#{0}”, NewReview.ProductReviewID

)

);

}

}

Let’s go over this code in detail First, you can see that the input parameters to the new

AddProductReviewmethod include a ProductReviewIdas well as most of the properties

that make up a row in Production.ProductReview Next, using C#’s new newsyntax, you

instantiate a ProductReviewobject (NewReview) representing a row to be added to

Trang 8

Production.ProductReview To make the insertion happen, you again rely on the

DataContextobject (Context) The syntax Context.ProductReviewsindicates that the

target table is Production.ProductReview

When you callInsertOnSubmitwith yourNewReviewobject as its parameter, your new

review is added to the table when you callSubmitChanges(one line further down in the

example) After that call, you can check your object to see if itsProductReviewID

prop-erty was magically populated due to the fact that the row was created in the database

(becauseProductReviewIDis bound to the table’s primary key, which is an

auto-incre-mental identity column) LINQ is great in this way because it keeps the contents of your

objects and data tables in sync

The next listing, Listing 45.5, illustrates how to perform a delete using LINQ to SQL

LISTING 45.5 Deleting Rows Using LINQ to SQL

public void DeleteProductReview(int ProductReviewId)

{

AdventureWorks2008DataContext Context =

new AdventureWorks2008DataContext();

ProductReview Review

= (from m in Context.ProductReviews

where m.ProductReviewID == ProductReviewId

select m).FirstOrDefault();

if (Review != null)

{

using (TransactionScope Tran = new TransactionScope())

{

Context.ProductReviews.DeleteOnSubmit(Review);

Context.SubmitChanges();

}

}

}

To run Listing 45.5, you need to add a reference to System.Transactionsand then add a

usingstatement for that namespace This addition to the code illustrates one way to use

transactions with LINQ and also preserves the integrity of your AdventureWorks2008data

Going over the example, the DeleteProductReviewmethod takes a ProductReviewIDvalue

as input It then looks up that record using a LINQ query, just as you would in T-SQL If

the record was found (that is, if the query returns a non-null value), you then create a new

transaction, in which you delete the record by calling DeleteOnSubmit Note that because

you do not call the Completemethod of the Tranobject, the transaction is implicitly

rolled back

Trang 9

Listing 45.6 rounds out our LINQ examples by showing you how to update a set of rows

LISTING 45.6 Updating Rows Using LINQ to SQL

public void UpdateProductInventories(int Threshold, short NewQty)

{

AdventureWorks2008DataContext Context =

new AdventureWorks2008DataContext();

List<ProductInventory> InventoryItems

= (from m in Context.ProductInventories

where m.Quantity < Threshold

select m).ToList();

if (InventoryItems.Count > 0)

{

using (TransactionScope Tran = new TransactionScope())

{

foreach (ProductInventory Item in InventoryItems)

{

Item.Quantity = NewQty;

}

Context.SubmitChanges();

}

}

}

In this listing, the query operates on a range of rows, rather than just one Using LINQ’s

ORM magic, you select rows from Production.ProductInventoryas a Listof

ProductInventoryby matching your Thresholdcriterion against the current Quantity

value of objects in DataContext.ProductInventories (Notice how LINQ even performs

grammatically correct pluralization of table names.) You iterate through each returned

object (again, within the scope of a transaction so as to keep AdventureWorks2008intact)

and then update the Quantityfor each Then you submit your changes Very simple, very

powerful, very much a timesaver

Although this LINQ to SQL primer covers the essentials, we highly recommend you dive

deeper into the NET namespaces you’ve seen to uncover all the possibilities LINQ to SQL

has to offer

Trang 10

Using ADO.NET Data Services

ADO.NET Data Services (ADODS) is a platform for providing SQL Server data to websites,

RIAs (such as Silverlight and Flash applications), and other Internet clients over standard

HTTP using modern web development conventions

Getting Set Up

To start using ADODS, you first need to download and install Visual Studio 2008 Service

Pack 1, as well as the NET Framework 3.5 Service Pack 1 These updates include support

for the Microsoft Entity Framework (EF), ADODS core, and ADODS NET client library A

second configuration step, required for viewing ADODS XML data in the examples that

follow, is an Internet Explorer 8 settings change: using the Tools menu, click Internet

Options Click the Content tab and then click the Settings button in the Feeds and Web

Slices group On the Feeds and Web Slices dialog, uncheck the Turn on Feed Reading View

check box Click OK twice

Essentials

To work with data provided by ADODS services, you make HTTP requests, each of which

must include three key parts:

A uniform resource identifier (URI), which addresses the data in question

An HTTP verb (either GET,POST,MERGE,PUT, or DELETE), which indicates the type of

CRUD operation to be performed

An HTTPAcceptheader, which indicates the format of the data being sent or received

As of this writing, ADODS services provide data to clients in one of two formats:

Atom Publishing Protocol (AtomPub)—An XML format that acts as an

applica-tion-level protocol for working with web resources (This is the default ADODS

response format For more information on Atom, visit

http://en.wikipedia.org/wiki/Atom_(standard).)

JavaScript Object Notation (JSON)—A text-based format for representing

serial-ized JavaScript objects Many popular Asynchronous JavaScript and XML (AJAX)

client libraries (including JQuery, Prototype, and YUI) include core support for

work-ing with JSON

ADODS services rely on EF to provide an abstract mapping layer between a physical data

model and CLR object model EF is a general-purpose ORM (similar to a LINQ to SQL class)

that works with a number of data providers, including SQL Server, Oracle, DB2, and MySQL

The first step in working with ADODS is to create an EF Entity Data Model (EDM) that

includes the objects you want to expose from theAdventureWorks2008database to the Web

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN