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

ASP.NET 4 Unleased - p 99 pps

10 94 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 461,49 KB

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

Nội dung

If, on the other hand, your database table were named Movies and your class were named Movie, you would need to supply the Name property for the Table attribute to map the correct table

Trang 1

Storage—Indicates a field where the value of the property is stored

UpdateCheck—Indicates whether the property participates in optimistic concurrency

comparisons

The Table attribute supports the following single property:

Name—Indicates the name of the database table that corresponds to the class

Some comments about these attributes are needed First, you don’t need to specify a Name

property when your property or class name corresponds to your database column or table

name If, on the other hand, your database table were named Movies and your class were

named Movie, you would need to supply the Name property for the Table attribute to map

the correct table to the class

Second, you always want to specify the primary key column by using the IsPrimaryKey

property For example, if you don’t specify a primary key column, you can’t do updates

against your database using LINQ

Finally, even though we didn’t do this in our Movie class, you almost always want to

include a timestamp column in your database table and indicate the timestamp column

by using the IsVersion property If you don’t do this, LINQ to SQL checks whether the

values of all the properties match the values of all the columns before performing an

update command to prevent concurrency conflicts If you specify a version property, LINQ

to SQL can check the value of this single property against the database rather than all the

columns

Now that we’ve created an entity, we can start performing queries against the database

using LINQ to SQL For example, the page in Listing 20.12 contains a form that enables

you to search for movies by a particular director

LISTING 20.12 Entities\SearchMovies.aspx

<%@ Page Language=”C#” %>

<%@ Import Namespace=”System.Web.Configuration” %>

<%@ Import Namespace=”System.Linq” %>

<%@ Import Namespace=”System.Data.Linq” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<script runat=”server”>

protected void btnSearch_Click(object sender, EventArgs e)

{

string conString = WebConfigurationManager

ConnectionStrings[“Movies”].ConnectionString;

DataContext db = new DataContext(conString);

var tMovie = db.GetTable<Movie>();

Trang 2

grdMovies.DataSource = tMovie.Where( m => m.Director.Contains(

txtDirector.Text) );

grdMovies.DataBind();

}

</script>

<html xmlns=”http://www.w3.org/1999/xhtml”>

<head runat=”server”>

<title>SearchMovies.aspx</title>

</head>

<body>

<form id=”form1” runat=”server”>

<div>

<asp:Label

id=”lblDirector”

Text=”Director:”

AssociatedControlID=”txtDirector”

Runat=”server” />

<asp:TextBox

id=”txtDirector”

Runat=”server” />

<asp:Button

id=”btnSearch”

Text=”Search”

OnClick=”btnSearch_Click”

Runat=”Server” />

<br /><br />

<asp:GridView

id=”grdMovies”

Runat=”server” />

</div>

</form>

</body>

</html>

When you click the Search button, the btnSearch_Click() method executes the LINQ to

SQL query

First, a DataContext is created by passing a database connection string to the class’s

constructor The DataContext is responsible for tracking all the LINQ to SQL entities and

representing the database connection

Trang 3

Next, a variable named tMovie is instantiated that represents a particular database table

from the DataContext Because we pass the Movie entity to the GetTable<T>() method()

method>, the method returns a Table<T> object that represents the Movie database table

The Table<T> object implements the IQueryable interface and can, therefore, be queried

with a LINQ to SQL query

Finally, the following LINQ to SQL query is executed:

tMovie.Where( m => m.Director.Contains(txtDirector.Text)

The lambda expression m => m.Director.Contains(txtDirector.Text) passed to the

Where() method returns every movie record from the database in which the Director

column contains the text entered into the TextBox control

We had to import two namespaces to use the LINQ to SQL query: System.Linq and

System.Data.Linq

NOTE

To keep things simple, I use the LINQ to SQL query directly within the ASP.NET page in

Listing 20.12 In real life, to avoid mixing user interface and Data Access layers, I

would perform the LINQ to SQL query in a separate class and use an

ObjectDataSource to represent the class

Building Entities with the LINQ to SQL Designer

As an alternative to building entities by hand, you can use the LINQ to SQL Designer

You can simply drag database tables from the Database Explorer (Server Explorer) onto

the Designer The Designer generates the entity classes with the correct attributes

automatically

Follow these steps to use the LINQ to SQL Designer:

1 Select Website, Add New Item to open the Add New Item dialog box

2 Select the LINQ to SQL Classes template, give it the name MyDatabase, and click the

Add button

3 When prompted to create the LINQ to SQL classes in the App_Code folder, click the

Yes button

4 After the LINQ to SQL Designer opens, drag one or more database tables from the

Database Explorer/Server Explorer window onto the Designer surface

You can view the code that the Designer generates by expanding the MyDatabase.dbml

node in the App_Code folder and double-clicking the MyDatabase.designer.cs file

The Designer generates a strongly typed DataContext class named MyDatabaseContext

Each database table that you drag onto the Designer surface gets exposed by the

DataContext class as a strongly typed property

Trang 4

The Designer, furthermore, generates a distinct class for each database table you drag onto

the Designer For example, after you drag the Movie table onto the Designer, a new class

named Movie is created in the MyDatabase.designer.cs file

NOTE

The LINQ to SQL Designer attempts to pluralize table names automatically when you

add them to the Designer So, when you drag the Movie table onto the Designer, the

Designer generates a DataContext property named Movies Most of the time, but not

all of the time, it gets the pluralization right You can turn off this feature by selecting

Tools, Options and selecting the Database Tools, O/R Designer tab

The page in Listing 20.13 demonstrates how you can use the MyDatabaseContext class

when performing a LINQ to SQL query (after dragging the Movies database table onto the

LINQ to SQL Designer)

LISTING 20.13 Entities\ListMoviesByBoxOffice.aspx

<%@ Page Language=”C#” %>

<%@ Import Namespace=”System.Linq” %>

<%@ Import Namespace=”System.Data.Linq” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<script runat=”server”>

void Page_Load()

{

MyDatabaseDataContext db = new MyDatabaseDataContext();

grd.DataSource = db.Movies.OrderBy(m => m.BoxOfficeTotals);

grd.DataBind();

}

</script>

<html xmlns=”http://www.w3.org/1999/xhtml”>

<head runat=”server”>

<title>List Movies by Box Office</title>

</head>

<body>

<form id=”form1” runat=”server”>

<div>

<asp:GridView

id=”grd”

runat=”server” />

Trang 5

</div>

</form>

</body>

</html>

The page in Listing 20.13 displays a list of all movies in order of the movie’s box office totals

The LINQ to SQL Designer creates partial classes for each table you drag onto the Designer

surface This means that you extend the functionality of each entity by creating a new

partial class For example, the class in Listing 20.14 extends the Movie class that the LINQ

to SQL Designer generates

LISTING 20.14 Entities\App_Code\Movie.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Data.Linq;

public partial class Movie

{

public static IEnumerable<Movie> Select()

{

MyDatabaseDataContext db = new MyDatabaseDataContext();

return db.Movies;

}

public static IEnumerable<Movie> SelectByBoxOfficeTotals()

{

return Select().OrderBy( m => m.BoxOfficeTotals);

}

}

The Movie class in Listing 20.14 is declared as a partial class It extends the partial class in

the MyDatabase.designer.cs file by adding both a Select() method and a

SelectByBoxOfficeTotals() method

NOTE

The SelectByBoxOfficeTotals() method calls the Select() method It is important

to understand that this does not cause two SQL SELECT commands to be executed

against the database Until the GridView control starts iterating through the results of

the LINQ to SQL query, you are just building an expression

Trang 6

The page in Listing 20.15 demonstrates how you represent the Movie class with an

ObjectDataSource control

LISTING 20.15 Entities\PartialMovie.aspx

<%@ Page Language=”C#” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml”>

<head runat=”server”>

<title>Partial Movie</title>

</head>

<body>

<form id=”form1” runat=”server”>

<div>

<asp:GridView

id=”grdMovies”

DataSourceID=”srcMovies”

Runat=”server” />

<asp:ObjectDataSource

id=”srcMovies”

TypeName=”Movie”

SelectMethod=”SelectByBoxOfficeTotals”

runat=”server” />

</div>

</form>

</body>

</html>

There is no code in the page in Listing 20.15 All the code is where it should be, in the

Data Access layer implemented by the Movie class

Building Entity Associations

One entity can be associated with another entity For example, a MovieCategory entity

might be associated with one or more Movie entities

If you have defined foreign key relationships between your database tables, these

rela-tionships are preserved when you drag your tables onto the LINQ to SQL Designer The

LINQ to SQL Designer generates entity associations based on the foreign key relationships

automatically

Trang 7

For example, the MovieCategory entity is related to the Movie entity through the Movie

entity’s CategoryId property As long as you have defined a foreign key relationship

between Movie.CategoryId and MovieCategory.Id, you can use a query like this

following:

MyDatabaseDataContext db = new MyDatabaseDataContext();

var category = db.MovieCategories.Single( c => c.Name == “Drama” );

var query = category.Movies;

The second statement grabs the Drama movie category The third statement returns all

movies associated with the Drama movie category In this case, we’ve followed a

one-to-many relationship and got a list of movies that match a movie category You can also go

the opposite direction and retrieve the only movie category that matches a particular

movie:

string categoryName = db.Movies.Single(m=>m.Id==1).MovieCategory.Name;

This query retrieves the name of the movie category associated with the movie that has

an ID of 1

NOTE

Under the covers, the LINQ to SQL Designer creates the entity relationships by adding

association attributes to entity properties The LINQ to SQL Designer also adds some

tricky synchronization logic to keep the properties of associated entities synchronized

Although I wish that I could code all my entities by hand, adding all the logic necessary

to get the entity associations to work correctly is too much work For that reason, I use

the LINQ to SQL Designer

Using the LinqDataSource Control

I want to briefly describe the LinqDataSource control You can use this control to

repre-sent LINQ queries For example, the page in Listing 20.16 contains a simple search form

for searching movies by director The page uses a LinqDataSource to represent the LINQ

query

LISTING 20.16 Entities\ShowLinqDataSource.aspx

<%@ Page Language=”C#” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml”>

<head runat=”server”>

<title>Show LinqDataSource</title>

</head>

<body>

Trang 8

<form id=”form1” runat=”server”>

<div>

<asp:Label

id=”lblSearch”

AssociatedControlID=”txtSearch”

Text=”Search:”

Runat=”server” />

<asp:TextBox

id=”txtSearch”

Runat=”server” />

<asp:Button

id=”btnSearch”

Text=”Search”

Runat=”server” />

<br /><br />

<asp:GridView

id=”grd”

DataSourceID=”LinqDataSource1”

Runat=”server” />

<asp:LinqDataSource

ID=”LinqDataSource1”

ContextTypeName=”MyDatabaseDataContext”

TableName=”Movies”

Where=”Director == @Director”

OrderBy=”DateReleased”

Select=”new (Title, Director)”

runat=”server”>

<whereparameters>

<asp:controlparameter Name=”Director”

ControlID=”txtSearch”

PropertyName=”Text”

Type=”String” />

</whereparameters>

</asp:LinqDataSource>

</div>

</form>

</body>

</html>

Trang 9

The LinqDataSource in Listing 20.16 represents the following LINQ query:

var query = db.Movies

.Where(m => m.Director == txtSearch.Text)

.OrderBy(m => m.DateReleased)

.Select(m => new {m.Title, m.Director});

You also can use the LinqDataSource to generate Update, Insert, and Delete LINQ

queries automatically Simply set the EnableInsert, EnableUpdate, or EnableDelete

property to the value True For example, the page in Listing 20.17 contains a

DetailsView control and a GridView control that you can use to insert, edit, and delete

movie records The inserting, editing, and deleting is performed by the LinqDataSource

control

LISTING 20.17 Entities\EditLinqDataSource.aspx

<%@ Page Language=”C#” %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<script runat=”server”>

protected void frmMovie_ItemInserted

(

object sender,

DetailsViewInsertedEventArgs e

)

{

grdMovies.DataBind();

}

</script>

<html xmlns=”http://www.w3.org/1999/xhtml”>

<head runat=”server”>

<title>Edit LinqDataSource</title>

</head>

<body>

<form id=”form1” runat=”server”>

<div>

<asp:DetailsView

id=”frmMovie”

DataSourceID=”srcMovies”

DefaultMode=”Insert”

AutoGenerateRows=”false”

AutoGenerateInsertButton=”true”

Runat=”server” OnItemInserted=”frmMovie_ItemInserted”>

Trang 10

<Fields>

<asp:BoundField DataField=”Title” HeaderText=”Title” />

<asp:BoundField DataField=”Director” HeaderText=”Director” />

<asp:BoundField DataField=”DateReleased” HeaderText=”Date Released” />

</Fields>

</asp:DetailsView>

<br /><br />

<asp:GridView

id=”grdMovies”

DataKeyNames=”Id”

DataSourceID=”srcMovies”

AllowPaging=”true”

PageSize=”5”

AutoGenerateEditButton=”true”

AutoGenerateDeleteButton=”true”

Runat=”server” />

<asp:LinqDataSource

id=”srcMovies”

ContextTypeName=”MyDatabaseDataContext”

TableName=”Movies”

OrderBy=”Id descending”

EnableInsert=”true”

EnableUpdate=”true”

EnableDelete=”true”

AutoPage=”true”

Runat=”server” />

</div>

</form>

</body>

</html>

One other thing that you should notice about the LinqDataSource control in Listing

20.17: the LinqDataSource control has an AutoPage attribute set to the value True

When this property has the value True, the LinqDataSource performs data source paging

automatically

I don’t use the LinqDataSource control in production applications Instead, I wrap up all

my LINQ queries in a separate class and use the ObjectDataSource control to represent

the class The LinqDataSource control is similar to the SqlDataSource control in that both

controls are great for prototyping and doing demos, but they are not appropriate controls

to use in production applications

Ngày đăng: 06/07/2014, 18:20

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN