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

Hướng dẫn học Microsoft SQL Server 2008 part 85 pdf

10 369 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 0,94 MB

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

Nội dung

You should use LINQ to SQL when you want the following: ■ A rapid development cycle ■ An ORM solution and a 1:1 data/object model mapping ■ Optimized performance through stored procedure

Trang 1

LINQ to Entities is more than a simple ORM tool The ADO.NET Entity Framework and LINQ to

Enti-ties enable developers to work against a conceptual model that offers more flexible mapping, which

pro-vides the capability to utilize a wider degree of variance from the underlying data source

What determines whether a project should use LINQ to SQL or LINQ to Entities/Entity Framework?

You should use LINQ to SQL when you want the following:

■ A rapid development cycle

■ An ORM solution and a 1:1 data/object model mapping

■ Optimized performance through stored procedures and compiled queries

■ To generate your own CLR classes versus using generated classes or deriving from base classes

In contrast, LINQ to Entities and the Entity Framework should be used when the following apply:

■ Your application targets different database engines in addition to Microsoft SQL Server

■ Your physical database structure could be significantly different from your object model That means you still want the benefits of an ORM but your classes may or may not map 1:1 with your database schema

■ You want to optimize performance through stored procedures and compiled queries

■ The LINQ query should work in a database vendor–neutral manner

■ You want to define application domain models to be used as the basis for a persistence layer This section introduces LINQ to Entities and the Entity Framework and illustrates by example how easy

it is to create entities and query them using LINQ

Everything needed to use LINQ to Entities and the Entity Framework is installed with Visual Studio

2008 SP1, which can be downloaded from the following location:

www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&displaylang=en

Creating and querying entities using LINQ

After installing the service pack, create a new Visual Studio C# Windows forms project When the

project is loaded, add a new item to it In the Add New Item dialog you will notice a new item in the

list of templates called ADO.NET Entity Data Model This Entity Data Model provides the capability

to define domain models for an application Select the ADO.NET Entity Data Model template, name it

AdventureWorks.edmx, and then click OK

The Entity Data Model wizard begins The first screen of the wizard provides the capability to define the

model contents The model can be created from scratch, by selecting Empty Model, or generated from a

database, by selecting Generate from Database By default, Generate from Database is selected, so ensure

that this option is selected and click Next

The next step of the wizard defines the data connection If a connection has previously been defined,

you can select it from the drop-down menu If not, click the New Connection button and define a

Trang 2

connection in the Connection Properties dialog You are also asked at this step whether or not you want

to store sensitive connection information in the connection string The connection string information

is stored in the application configuration file (app.config) and is used by theObjectContext

to connect to the database Excluding the sensitive data (such as password information) from the

connection string requires that the information be set in the application code Including the sensitive

data includes it in clear text in theapp.config For production environments, it is recommended that

sensitive information be excluded from the connection string For the purposes of this example, select

the option to include the sensitive information in the connection string

Once the connection has been defined, click Next

The next step of the wizard enables you to select the objects to be included in the model

Objects such as tables, views, and stored procedures can be selected for inclusion For this

example, select thePerson.Contact,HumanResources.Employee,Sales.Customer, and

Sales.SalesOrderHeadertables

In addition, it is at this step of the wizard that the model namespace must be entered It defaults to a

value, but it is good to verify that there is a value By default, it takes the object name entered when the

ADO.NET Entity Data Model template was selected, which in this example is AdventureWorks, and then

adds the word ‘‘Model’’ to the end Thus, the namespace should default toAdventureWorksModelin

this example Click Finish

The wizard then builds the Entity Data Model based on the objects and selections in the wizard When

it is complete, the Entity Data Model Designer opens in the Visual Studio IDE

This process is very familiar to the LINQ to SQL example shown earlier The difference is that with

LINQ to SQL, the database objects were added in the model after the designer was created With the

Entity Framework, a wizard walks the developer through the steps of selecting which objects to include

in the model prior to creating the designer and model.

When the creation of the model is complete, a new node appears in the Solution Explorer The

node is calledAdventureWorks.edmxand it has a child file, which is theDesignerfile called

AdventureWorks.Designer.cs

Opening the edmxfile opens the visual model designer that was created at the end of the wizard

Our focus here is theDesigner.csfile Opening that file displays some code that should look very

familiar TheDesigner.csfile contains theDataContextand all the necessary object mappings to

the database For example, one of the first lines that should look familiar is the creation of a class that

inherits from theDataContext:

public partial class AdventureWorksEntities :

global::System.Data.Objects.ObjectContext

Also different is the way tables are defined Instead of applying the[Table]attribute, as done in LINQ

to SQL, this class inherits from theEntityObjectclass, which is the base class for entity types that

are generated via the Entity Data Model tools, as shown here:

public partial class Employee :

global::System.Data.Objects.DataClasses.EntityObject

Trang 3

The class is also attributed with several attributes, such asAdmEntityTypeAttribute, which

indi-cates that the class represents an entity type:

[global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute (NamespaceName="AdventureWorksModel", Name="Employee")]

[global::System.Runtime.Serialization.DataContractAttribute (IsReference=true)]

[global::System.Serializable()]

public partial class Employee : global::System.Data.Objects.DataClasses.EntityObject

Also different is the way in which columns are defined and mapped Instead of using the[Column]

attribute, as done in LINQ to SQL, columns are attributed with theEdmScalarProperty

Attribute, which indicates that the property represents a scalar property:

[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute (EntityKeyProperty=true, IsNullable=false)]

[global::System.Runtime.Serialization.DataMemberAttribute()]

public int EmployeeID

Another important item to look at is the set of relationship attributes TheEdmRelationship

Attributeis used to define a relationship between two entity types (in this case, Contacts and

Employees) based on an association in the conception model:

[assembly: global::System.Data.Objects.DataClasses EdmRelationshipAttribute("AdventureWorksModel",

"FK_Employee_Contact_ContactID", "Contact", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(EF.Contact), "Employee",

global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(EF.Employee))]

With that background, it is time to focus on the front end Open the form in design view and place a

list box and a button on the form In the Click event of the button, add the following code:

AdventureWorksEntities awe = new AdventureWorksEntities();

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

foreach (var emp1 in query) listBox1.Items.Add(emp1.LastName);

By now this code should look very familiar It looks almost exactly like the LINQ to SQL code The first

line creates an instance of theAdventureWorksEntitiesclass, followed by a LINQ query

expres-sion The query is then iterated through and the results displayed in the list box

Trang 4

Compile the project and then run it When the form displays, click the button The list box will display

results, some of which are shown here:

Agcaoili

Jacobson

Altamirano

Alvarado

Appelbaum

Ayers

Querying multiple tables using LINQ to Entities and the Entity

Framework

This chapter closes with one last example that illustrates how to query multiple tables using LINQ to

Entities and the Entity Framework

Place another button the form, and in the Click event add the following code:

AdventureWorksEntities awe = new AdventureWorksEntities();

var query =

from cus in awe.Customer

where cus.CustomerID == 2

select cus;

foreach (var cust in query)

{

listBox1.Items.Add(cust.CustomerID);

foreach (var ord in cust.SalesOrderHeader)

listBox1.Items.Add(" " + ord.OrderDate);

}

This example begins like the previous example, but theforeachloops are different The LINQ query

returns a single record, where the CustomerID column in theSalestable is 2 In theforeachloop,

that same CustomerID is written to the list box, and then a secondary loop loops through the orders for

that customerID

Compile the application and run it When the form displays, click button2 The list box displays the

CustomerID, but it does not display the sales order header rows for that customer That is because the

query fetched the customer but it did not fetch the orders Because the Entity Framework did not know

how the orders were going to be used, it did not want to automatically bring back information that was

not needed

To fix that, the orders can be explicitly loaded for that specific customer by adding the following

high-lighted line of code to the firstforeachloop:

foreach (var cust in query)

{

listBox1.Items.Add(cust.CustomerID);

Trang 5

foreach (var ord in cust.SalesOrderHeader) listBox1.Items.Add(" " + ord.OrderDate);

}

When theforeachis executed, it will execute the query to return the customers, but not the orders

When theLoad()statement is executed, it will create a separate query and return the orders for that

customer

Run the project again and click button2 This time the list box will display the order dates for

CustomerID 2:

2 8/1/2002 11/1/2002 2/1/2003 5/1/2003 8/1/2003 11/1/2003 2/1/2004 5/1/2004

The preceding query is OK if the goal is to load only orders for some of the customers (for example,

when selecting a customer from a list), but in this case there exists a loop that will bring back every

order for every customer Therefore, instead of executing multiple queries, a request can be made to

only pull back all of the orders with the customer in the initial query, as follows:

var query = from cus in awe.Customer.Include("SalesOrderHeader") where cus.CustomerID == 2

select cus;

When the application is run again, the results displayed in the text box are the same as the previous

query

The goal of these two examples is to illustrate how easy LINQ to Entities and the Entity Framework

are to access SQL Server and query entities With all that was shown in this chapter, it should be very

apparent how flexible yet powerful LINQ is for querying different data sources such as XML, DataSets,

and Entities

Your homework assignment for this section is to create a new EF model This time, however, in the

wiz-ard use an empty model, add one or more tables to it, and then write a LINQ query to query the data

Summary

The purpose of this chapter was to provide an overview of LINQ and the different LINQ providers, and

show by example how powerful, flexible, and efficient they are in accessing the different types of data

sources

In this chapter you learned what LINQ is and how to use LINQ to query data from different data

sources, such as XML, entities, and databases, using LINQ’s powerful standard query operators

Trang 6

Asynchronous Messaging

with Service Broker

IN THIS CHAPTER

Defining a work queue Queuing messages Managing conversations

Service Broker is a powerful yet simple work queue system that can be used

to add asynchronous messaging and work queues to a database abstraction

layer to provide high scalability, and it is essential in any SOA data store

architecture

If you’ve ever built a table to hold work to be done, such as orders to be

processed by a Materials Requirement Planning system, then you’ve built a work

queue In one application Service Broker is just that — a high-performance,

wide-payload work queue integrated into SQL Server with DDL and monitoring

capabilities

Service Broker can also be used to pass messages with guaranteed secure delivery

between work queues, which opens up a world of possibilities

Because Service Broker is essentially just a SQL Server table, it includes all the

cool transactional and back-up capabilities inherent to SQL Server This is what

sets Service Broker apart from other queuing technologies, such as Microsoft

Message Queuing (MSMQ)

The queue contains a single, wide column for the message body, which is OK

because the message will typically contain a single XML file or fragment or SOAP

message as the payload

Service Broker is not enabled by default so the first specific step to working with

Service Broker is to turn it on using theALTER DATABASEcommand:

ALTER DATABASE AdventureWorks SET ENABLE_BROKER;

Trang 7

What’s New with Service Broker?

Service Broker was introduced with much fanfare in SQL Server 2005 For SQL Server 2008, there are

a few slight enhancements: Conversations may now have an assigned priority; there are new DMVs for

monitoring Service Broker; there’s a new Service Broker Statistics Report; and Management Studio can now

auto-generate some Service Broker scripts

Configuring a Message Queue

Service Broker uses a messaging or dialog metaphor, but there’s much more to Service Broker than just

the messages The Service Broker objects must be defined in the following order:

1 Message types define the legal requirements of the message.

2 Contracts define the agreement between the initiating service and the target, including the

message type, the queue, and the services

3 Queues hold the lists of messages.

4 Services communicate with the queue and either send or receive messages as the initiating

service or the target service, respectively

Other than defining the message type as XML and naming the objects, there isn’t much complexity to

setting up a Service Broker database That’s because the data definition language, or DDL, does all the

work; Service Broker is a message-agnostic work queue that’s serving as an infrastructure for the

mes-sages There’s more work in placing messages on and taking messages off the queue

Because Service Broker is integrated within SQL Server, the objects are created using the familiar create

DDL commands

The first step in creating a Service Broker queue is to define a message type and a contract that uses that

message type:

CREATE MESSAGE TYPE HelloWorldMessage VALIDATION = WELL_FORMED_XML ; CREATE CONTRACT HelloWorldContract ( HelloWorldMessage SENT BY INITIATOR);

The initiator and target queues are also simply created using DDL:

CREATE QUEUE [dbo].[TargetQueue] ; CREATE QUEUE [dbo].[InitiatorQueue] ;

Likewise, the initiator and target services are also defined using DDL Both services are associated with a

queue, and the receiving, or target, service specifies that it can receive messages from a contract:

Trang 8

CREATE SERVICE InitiatorService

ON QUEUE [dbo].[InitiatorQueue];

GO

CREATE SERVICE TargetService

ON QUEUE [dbo].[TargetQueue]

(HelloWorldContract);

With the Service Broker objects created, you’ll be able to see them listed under the Object Explorer

Service Broker node

Working with Conversations

With the Service Broker object created, messages can be placed into the queue or received from the

queue Messages exist as part of a conversation that can be divided into conversation groups

Sending a message to the queue

The following code creates a conversation using aconversationhandleGUID TheBEGIN

CONVERSATIONcommand opens the conversation, and theSENDcommand actually places the message

into the queue:

BEGIN TRANSACTION ;

DECLARE @message XML ;

SET @message = N‘<message>Hello, World!</message>’ ;

DECLARE @conversationHandle UNIQUEIDENTIFIER ;

BEGIN DIALOG CONVERSATION @conversationHandle

FROM SERVICE [InitiatorService]

TO SERVICE ‘TargetService’

ON CONTRACT [HelloWorldContract]

WITH ENCRYPTION = OFF, LIFETIME = 1000 ;

SEND ON CONVERSATION @conversationHandle

MESSAGE TYPE [HelloWorldMessage]

(@message) ;

END CONVERSATION @conversationHandle ;

COMMIT TRANSACTION ;

To view the message in the queue, select from the queue table as if it

were a normal relational table:

SELECT CAST(message_body as nvarchar(MAX)) from [dbo].[TargetQueue]

Trang 9

Receiving a message

TheRECEIVEcommand will retrieve and remove the oldest message from the queue UseRECEIVE

within a transaction so that if something goes wrong, the receive can be rolled back and the message

will still be in the queue Service Broker is not a trigger that can code when a message is placed on the

queue; some code must run to extract the message To accomplish this, Microsoft added a new option

to theWAIT FORcommand, enabling it to wait for a message in the queue Without this option, the

code would have to run a loop to continuously check for a new message The following routine within

a stored procedure will wait for a message and then receive the top message from the queue:

USE AdventureWorks ; GO

Process all conversation groups

WHILE (1 = 1) BEGIN DECLARE @conversation_handle UNIQUEIDENTIFIER,

@conversation_group_id UNIQUEIDENTIFIER,

@message_body XML,

@message_type_name NVARCHAR(128);

BEGIN TRANSACTION ; Get next conversation group

WAITFOR(

GET CONVERSATION GROUP @conversation_group_id FROM [dbo].[TargetQueue]), TIMEOUT 500 ;

If there are no more conversation groups, roll back the transaction and break out of the outermost WHILE loop

IF @conversation_group_id IS NULL BEGIN

ROLLBACK TRANSACTION ; BREAK ;

END ; Process all messages in the conversation group Notice that all processing occurs in the same transaction

WHILE 1 = 1 BEGIN Receive the next message for the conversation group

Notice that the receive statement includes a WHERE clause to ensure that the messages received belong to the same conversation group

Trang 10

TOP(1)

@conversation_handle = conversation_handle,

@message_type_name = message_type_name,

@message_body =

CASE

WHEN validation = ‘X’ THEN CAST(message_body AS XML) ELSE CAST(N‘<none/>’ AS XML)

END

FROM [dbo].[TargetQueue]

WHERE conversation_group_id = @conversation_group_id ;

If there are no more messages, or an error occurred,

stop processing this conversation group

IF @@ROWCOUNT = 0 OR @@ERROR <> 0 BREAK;

Show the information received

SELECT ‘Conversation Group Id’ = @conversation_group_id,

‘Conversation Handle’ = @conversation_handle,

‘Message Type Name’ = @message_type_name,

‘Message Body’ = @message_body ;

If the message_type_name indicates that the message is

an error or an end dialog message, end the

conversation

IF @message_type_name

=’http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog’

OR @message_type_name

=’http://schemas.microsoft.com/SQL/ServiceBroker/Error’

BEGIN

END CONVERSATION @conversation_handle ;

END ;

END; Process all messages in conversation group

Commit the receive statements and the end conversation

statement

COMMIT TRANSACTION ;

END ; Process all conversation groups

use tempdb;;

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

TỪ KHÓA LIÊN QUAN