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

ASP.NET 4 Unleased - p 102 ppsx

10 213 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

Tiêu đề Data Access with LINQ to SQL
Trường học Standard University
Chuyên ngành Computer Science
Thể loại Thesis
Năm xuất bản 2023
Thành phố City Name
Định dạng
Số trang 10
Dung lượng 803,41 KB

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

Nội dung

The class in Listing 20.29 contains a method called GetDynamicSort that returns a dynamic lambda expression that can be used with either the OrderBy or OrderByDescendingmethod.. using Sy

Trang 1

You can build LINQ to SQL query expressions dynamically by taking advantage of the

System.Linq.Expressions.Expression class This class contains all the methods for

build-ing query expressions dynamically Here is a (very partial) list of methods supported by

this class:

Add()—Creates an expression that represents addition.

And()—Creates an expression that represents a logical AND.

Condition()—Creates an expression that represents a condition.

Constant()—Creates an expression that represents a constant value.

Convert()—Creates an expression that represents a conversion from one type to

another

Divide()—Creates an expression that represents division.

Equal()—Creates an expression that represents whether two expressions are equal.

Field()—Creates an expression that represents a field.

Lambda()—Creates a lambda expression.

Multiply()—Creates an expression that represents multiplication.

Or()—Creates an expression that represents a logical OR.

Parameter()—Creates an expression that represents a function parameter.

Property()—Creates an expression that represents accessing a property.

PropertyOrField()—Creates an expression that represents accessing a property or

field

Subtract()—Creates an expression that represents subtraction.

Again, this is not a complete list of methods supported by the Expression class However,

it should give you some idea of how you can go about building expressions

Let’s discuss a real-world situation in which you need dynamic LINQ to SQL expressions:

sorting If you want to enable sorting when using a GridView control with LINQ to SQL,

you have a choice You can create a switch (SELECT CASE) block to sort by every possible

column that a user can click, or you can create a dynamic LINQ to SQL expression

The class in Listing 20.29 contains a method called GetDynamicSort() that returns a

dynamic lambda expression that can be used with either the OrderBy() or

OrderByDescending()method

LISTING 20.29 Standard\App_Code\Movie.cs

using System;

using System.Web;

using System.Collections.Generic;

using System.Linq;

Trang 2

using System.Linq.Expressions;

using System.Data.Linq;

using System.Reflection;

public partial class Movie

{

public static IEnumerable<Movie> Select(string orderBy)

{

string orderByColumn = “Id”;

string orderByDirection = “asc”;

if (!String.IsNullOrEmpty(orderBy))

ParseOrderBy(orderBy, ref orderByColumn, ref orderByDirection);

MyDatabaseDataContext db = new MyDatabaseDataContext();

if (orderByDirection == “asc”)

return db.Movies.OrderBy(GetDynamicSort(orderByColumn));

else

return db.Movies.OrderByDescending(GetDynamicSort(orderByColumn));

}

public static void ParseOrderBy

(

string orderBy,

ref string orderByColumn,

ref string orderByDirection

)

{

string[] orderByParts = orderBy.Split(‘ ‘);

orderByColumn = orderByParts[0];

if (orderByParts.Length > 1)

orderByDirection = orderByParts[1].ToLower();

}

private static Expression<Func<Movie, string>> GetDynamicSort

(

string orderByColumn

)

{

// Create expression to represent Movie parameter into lambda expression

ParameterExpression pMovie = Expression.Parameter(typeof(Movie), “m”);

Trang 3

// Create expression to access value of order by column

PropertyInfo propInfo = typeof(Movie).GetProperty(orderByColumn);

MemberExpression m = Expression.MakeMemberAccess(pMovie, propInfo);

// Box it

UnaryExpression b = Expression.TypeAs(m, typeof(object));

// Convert to string

MethodInfo convertMethod = typeof(Convert).GetMethod(“ToString”,

new Type[] { typeof(object) });

MethodCallExpression c = Expression.Call(null, convertMethod, b);

// Return lambda

return Expression.Lambda<Func<Movie, string>>(c, pMovie);

}

}

The GetDynamicSort() method builds a lambda expression dynamically and creates an

expression that looks like this:

m => Convert.ToString(m.Id As Object)

When the LINQ to SQL query gets translated to SQL, the following SQL command is

executed:

SELECT [t0].[Id], [t0].[CategoryId], [t0].[Title],

[t0].[Director], [t0].[DateReleased], [t0].[InTheaters],

[t0].[BoxOfficeTotals], [t0].[Description], [t0].[Version]

FROM [dbo].[Movie] AS [t0]

ORDER BY CONVERT(NVarChar(MAX),[t0].[Title])

You can use the class in Listing 20.29 with the ASP.NET page in Listing 20.30 When you

click a header column in GridView, it is sorted by the column

LISTING 20.30 Standard\ShowDynamicSort.aspx

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

<!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 Dynamic Sort</title>

</head>

<body>

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

<div>

Trang 4

<asp:GridView

id=”grdMovies”

DataSourceId=”srcMovies”

AllowSorting=”true”

Runat=”server” />

<asp:ObjectDataSource

id=”srcMovies”

TypeName=”Movie”

SelectMethod=”Select”

SortParameterName=”orderBy”

Runat=”server” />

</div>

</form>

</body>

</html>

The GridView control has its AllowSorting attribute set to the value true and the

ObjectDataSource control has its SortParameterName attribute set to the value orderBy

The page is set up to enable data source paging

NOTE

The GetDynamicSort() method described in this section does a sort after converting

the values of a column to strings For nonstring data types such as dates and integers,

doing string sorts produces the wrong results For example, after sorting, the id column

is ordered as 10, 2, 22, 29, 3, 30, 31, and so on

In the final part of this chapter, you learn how to create a custom entity base class that

implements a more sophisticated version of a dynamic sort that sorts different column

types correctly

Debugging LINQ to SQL

For the sake of performance, you had better know what is going on beneath the covers

when you execute LINQ to SQL queries In particular, it is useful to know how your LINQ

to SQL queries get translated into SQL and when your LINQ to SQL queries execute In

this section, I describe three methods of debugging LINQ to SQL

Trang 5

Using the LINQ to SQL Debug Visualizer

The LINQ to SQL Debug Visualizer is a useful tool for viewing how a LINQ to SQL query

translates into SQL The LINQ to SQL Debug Visualizer is not included with NET

Framework You need to download it from the following address: http://www.scottgu.com/

blogposts/linqquery/SqlServerQueryVisualizer.zip

After you download the LINQ to SQL Visualizer, you can use it like other Visualizers in

Visual Web Developer and Visual Studio by compiling it and placing the resulting DLL in

the My Documents\Visual Studio 2010\Visualizers folder Then, If you set a breakpoint

after a LINQ to SQL query and hover your mouse over the query, you can click the

magni-fying glass to see the full SQL command into which the query gets translated (see Figure

20.1) You also have the option of executing the SQL query directly from the Visualizer

FIGURE 20.1 Using the LINQ to SQL Debug Visualizer

Logging LINQ to SQL Queries

My favorite method of debugging LINQ to SQL queries is to log all the DataContext

output to ASP.NET trace That way, I can see all the LINQ to SQL queries that execute at

the bottom of each of my ASP.NET pages (see Figure 20.2)

The DataContext class includes a Log property You can assign a TextWriter to the Log

property, and DataContext writes to this TextWriter whenever it executes a query

Unfortunately, the NET Framework does not include a TextWriter that writes to ASP.NET

Trace Fortunately, it is not that difficult to write one, and I’ve included the code for a

Trace TextWriter in Listing 20.31

Trang 6

LISTING 20.31 Standard\TraceWriter.cs

using System;

using System.Text;

using System.Web;

using System.IO;

using System.Globalization;

public class TraceWriter : TextWriter

{

public override void Write(string value)

{

HttpContext.Current.Trace.Warn(value);

}

public override void Write(char[] buffer, int index, int count)

{

HttpContext.Current.Trace.Warn(“Linq”, new string(buffer, index, count));

}

public override Encoding Encoding

{

FIGURE 20.2 Logging LINQ to Trace

Trang 7

get { return Encoding.Unicode; }

}

public TraceWriter()

: base(CultureInfo.CurrentCulture)

{

}

}

After you drop the class in Listing 20.31 in your App_Code folder, you can set the

DataContext class to write to the TraceWriter like this:

MyDatabaseDataContext db = new MyDatabaseDataContext();

db.Log = new TraceWriter();

grd.DataSource = db.Movies.Where(m=>m.Id==2);

grd.DataBind();

After you set up the TraceWriter, you can enable Trace (by adding the Trace=”true” attribute

to the <%@ Page %> directive) on any page that uses a LINQ query and view the output

NOTE

The LINQ entity base class we create in the last part of this chapter automatically logs

all output to the TraceWriter

Using the GetCommand Method

Finally, you can use the DataContext.GetCommand() method to get the ADO.NET

command object that executes when a LINQ to SQL query executes After you grab the

command object, you can examine its parameters or its command text

The following code assigns the command text of a command associated with a LINQ to

SQL query to a Label control:

MyDatabaseDataContext db = new MyDatabaseDataContext();

var query = db.Movies.Where(m=>m.Id==2);

lblQuery.Text = db.GetCommand(query).CommandText;

The following SELECT command is displayed in the Label control:

SELECT [t0].[Id], [t0].[CategoryId], [t0].[Title], [t0].[Director],

[t0].[DateReleased], [t0].[InTheaters], [t0].[BoxOfficeTotals],

[t0].[Description],

[t0].[Version] FROM [dbo].[Movie] AS [t0] WHERE [t0].[Id] = @p0

Trang 8

Creating a Custom LINQ Entity Base Class

In this final part of this chapter, we build a custom LINQ to SQL base class Our base class

contains standard methods for selecting records, inserting records, updating records, and

deleting records It also supports paging and caching Finally, our base class contains

methods for performing validation

The files for the custom classes can be found on the website that accompanies this book

in the folder EntityBaseClasses This folder contains the following files:

EntityBase—A custom base class for LINQ to SQL entities.

EntityDataSource—A custom data source control derived from the

ObjectDataSource control for representing LINQ to SQL entities

EntityValidator—A custom validation control.

EntityCallOutValidator—A custom validation control that displays a call-out

vali-dation error message

ValidationError—A class that represents a validation error.

ValidationErrorCollection—A collection of validation errors.

ValidationException—An exception thrown when there is a validation error.

TraceWriter—A class for logging LINQ to SQL queries to ASP.NET trace.

The motivation for writing these classes was to make standard database operations easier

when using LINQ to SQL I discovered that I was writing the exact same queries and

commands over and over again whenever I created a new entity Writing a standard base

class made my life easier because it freed me from writing the same repetitive code

Using the Entity Base Class

Follow these steps to use the custom entity base classes:

1 Create a new website

2 Add an App_Code folder to your website, and copy the EntityBaseClasses folder to

the App_Code folder

3 Create one or more LINQ to SQL entities with the help of the LINQ to SQL Designer

4 Add a connection string named con to your database in the web.config file

5 Create a separate partial class for each LINQ to SQL entity and derive the class from

the EntityBase class

6 Create an empty Validate() method for each entity class

For example, imagine that you have used the LINQ to SQL Designer to create an entity

named Movie You created the Movie entity by dragging the Movie database table from the

Database Explorer (Server Explorer) window onto the LINQ to SQL Designer surface At

this point, you are ready to inherit your new Movie entity from the EntityBase class

Trang 9

Listing 20.32 contains the file that you add to your website to create a Movie entity that

inherits from the EntityBase class

LISTING 20.32 ShowEntityBase\App_Code\Movie.cs

using System;

public partial class Movie : EntityBase<Movie>

{

protected override void Validate()

{

}

}

Now that you have derived the Movie entity from EntityBase, the Movie class inherits

methods for selecting, inserting, updating, and deleting records

Performing Standard Data-Access Operations with the EntityBase

Class

Any entity that you inherit from the EntityBase class inherits the following methods

automatically:

Select()—Selects all entities.

Select(string orderBy)—Selects all entities in a certain order.

SelectCached()—Selects all entities from the cache.

SelectCached(string orderBy)—Selects all entities from the cache in a certain

order

Select(int startRowIndex, int maximumRows)—Selects a page of entities.

Select(int startRowIndex, int maximumRows, orderBy)—Selects a page of entities

in a certain order

SelectCount()—Returns a count of entities.

SelectCount(string orderBy)—Returns a count of entities.

SelectCountCached()—Returns a count of entities from the cache.

Get(int? Id)—Gets a single entity using the entity’s identity value.

Save(T oldEntity, T newEntity)—Either performs an insert or update depending

on whether the identity value is 0

Insert(T entityToInsert)—Inserts a new entity.

Update(T oldEntity, T newEntity)—Updates an existing entity.

Trang 10

Two of these methods—Get() and Save()—require that the database table an entity

repre-sents include an identity column The other methods do not make this assumption

The page in Listing 20.33 illustrates how you can use these methods

LISTING 20.33 ShowEntityBase\SelectPagedSortedMovies.aspx

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

<!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 id=”Head1” runat=”server”>

<title>Select Paged Sorted Movies</title>

</head>

<body>

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

<div>

<asp:GridView

id=”grdMovies”

DataSourceId=”srcMovies”

AllowPaging=”true”

AllowSorting=”true”

Runat=”server” />

<asp:ObjectDataSource

id=”srcMovies”

TypeName=”Movie”

SelectMethod=”Select”

EnablePaging=”true”

SelectCountMethod=”SelectCountCached”

SortParameterName=”orderBy”

Runat=”Server” />

</div>

</form>

</body>

</html>

The page in Listing 20.33 contains a GridView control bound to an ObjectDataSource

control The ObjectDataSource control represents the Movie entity The ObjectDataSource

is configured to support data source paging and sorting You get both the Select() and

SelectCountCached() methods for free from the EntityBase class

The EntityBaseClasses folder also contains a control named EntityDataSource, which can

be used instead of the normal ObjectDataSource The EntityDataSource control inherits

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

TỪ KHÓA LIÊN QUAN

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

TÀI LIỆU LIÊN QUAN