饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 74 页

作者:Nick Randolph/等 当前章节:15412 字 更新时间:2026-6-18 14:51

AdventureWorksDM.dbml. If you had chosen to create an Entities Dynamic Data project earlier you

would select the ADO.NET Entity Data Model instead.

After you click Add, the new item will open in the Object Relational Designer. Double-click the

AdventureWorksLT database file you added earlier to open it in the Server Explorer and then

expand the Tables node. Select all tables, except the first two, and drag them onto the Designer.

This populates the LINQ to SQL data model as shown in Figure 23-2.

fiGure 23-2

Finally, you’ll need to register your data model with Dynamic Data and enable scaffolding.

Open the Global.asax.cs (or Global.asax.vb if you are using Visual Basic) and locate

the following line of code. Uncomment this line and change the YourDataContextType to

AdventureWorksDMDataContext. Lastly, change the ScaffoldAllTables property to true.

c#

DefaultModel.RegisterContext(typeof(AdventureWorksDMDataContext),

new ContextConfiguration()

{ ScaffoldAllTables = true });

Code snippet Global.asax.cs

Creating a Dynamic Data Web application .

489

Vb

DefaultModel.RegisterContext(GetType(AdventureWorksDMDataContext), _

New ContextConfiguration() _

With {.ScaffoldAllTables = True})

Code snippet Global.asax.vb

That is all you need to do to get a data-driven web application with full CRUD support up

and running.

exploring a dynamic data application

When you run the application, it opens with the home page, Default.aspx, which displays a list

of hyperlinks for all the tables you added to the data model (see Figure 23-3). Note that the names

listed on this page are pluralized versions of the table name.

fiGure 23-3

When you click one of these links, you are taken to the List.aspx page, shown in Figure 23-4,

for the selected table. This page, along with the Details.aspx page for an individual record,

represents the “Read” function of your CRUD application and includes support for paging and

filtering of the records by foreign key. This page also displays links to view details, edit, or delete a

record. Any foreign keys are displayed as links to a details page for that foreign key record.

490 .

chaPter 23 dynAmic dATA

fiGure 23-4

You may notice that some database fields are missing from the web page, such

as ProductID and ThumbNailPhoto. By default, Dynamic Data will not

scaffold Identity columns, binary columns, or computed columns. This can be

overridden, as you will find out later in this chapter.

The “Update” CRUD function is accessed by clicking the Edit link against a record. This displays

the Edit.aspx page, as shown in Figure 23-5. You will notice that the textboxes are different

widths — this is determined based on the length of the database field. This page also includes a

number of ASP.NET validation controls, based on database field information. For example, the

ProductNumber field has a RequiredFieldValidator because the underlying database field is

not nullable. Likewise, the Weight field uses a CompareValidator to ensure that the value

entered is a decimal.

Foreign keys are also handled by drop-down selectors. For example, in Figure 23-5 the

ProductCategory and ProductModel fields are foreign keys. Tables that use the selected table as

a foreign key are displayed as hyperlinks. This can be seen in the SalesOrderDetails field in

Figure 23 - 5.

Customizing the Data Model .

491

fiGure 23-5

custoMizinG the data Model

While scaffolding an entire database makes for an impressive demo, it is unlikely that you would

actually want to expose every table and field in your database to end users. Fortunately, Dynamic

Data has been designed to handle this scenario, and many others, by customizing the data model.

scaffolding individual tables

Before you begin customizing the data model you should disable automatic scaffolding of all tables.

Open the Global.asax.cs file and change the ScaffoldAllTables property to false.

The next step is to selectively enable scaffolding for individual tables. Begin by adding a new class

file to the project called Product.cs. This class must be a partial class, because Product is already

defined in the LINQ to SQL data model. To enable scaffolding for the Product table, decorate

the class with the ScaffoldTable attribute. Once completed, the class should look similar to the

following code:

492 .

chaPter 23 dynAmic dATA

c#

using System.ComponentModel.DataAnnotations;

namespace DynDataWebApp

{

[ScaffoldTable(true)]

public partial class Product

{

}

}

Code snippet Product.cs

Vb

Imports System.ComponentModel.DataAnnotations

< ScaffoldTable(True) > _

Partial Public Class Product

End Class

Code snippet Product.vb

If you run the application now only the Product table will be listed and editable.

You can achieve the same result by leaving the ScaffoldAllTables property to

true and selectively hiding tables by decorating their corresponding classes with

the ScaffoldTable attribute set to false.

customizing individual data fields

In many cases you will want certain fields in a table to be either read only or hidden. This is

particularly useful if the table contains sensitive data such as credit card information.

For example, when you edit a record in the Products table, it displays a link to the SalesOrderDetails

table. This link is disabled because the SalesOrderDetails table has not been enabled for scaffolding.

Therefore displaying this field provides the user with no useful information. Also the ModifiedDate

field, while useful for end users to know, is not something that you would typically want them to

edit directly. Therefore it would be better to display this field as read only and allow the database

to modify it with an Update trigger.

These requirements are supported by Dynamic Data by adding a metadata class to your data model

class. In the Product.cs file add a new class to the bottom of the file called ProductMetadata.

This class can be associated by applying the MetadataType attribute to the Product class.

Customizing the Data Model .

493

In the ProductMetadata class, create public fields with the same name as each data field that you

want to customize. Because Dynamic Data will read the type of this field from the data model class

rather than the metadata class, you can use object as the type for these fields.

Add the ScaffoldColumn attribute to the SalesOrderDetails field and set it to false to hide the

field. To make the ModifiedDate field read only, decorate it with an Editable attribute that is set

to false.

The following code shows these changes:

c#

namespace DynDataWebApp

{

[ScaffoldTable(true)]

[MetadataType(typeof(ProductMetadata))]

public partial class Product

{

}

public class ProductMetadata

{

[ScaffoldColumn(false)]

public object SalesOrderDetails;

[Editable(false)]

public object ModifiedDate;

}

}

Code snippet Product.cs

Vb

<ScaffoldTable(True)> _

<MetadataType(GetType(ProductMetadata))> _

Partial Public Class Product

End Class

Public Class ProductMetadata

<ScaffoldColumn(False)> _

Public SalesOrderDetails As Object

<Editable(False)> _

Public ModifiedDate As Object

End Class

Code snippet Product.vb

Figure 23-6 shows the results of these changes in action. On the left is the original edit screen for

the Product table. On the right is the new edit screen after the data model has been customized.

494 .

chaPter 23 dynAmic dATA

fiGure 23-6

adding custom Validation rules

As mentioned earlier in this chapter, Dynamic Data includes some built-in support for validation

rules that are inferred from the underlying database schema. For example, if a field in a database

table is marked as not nullable, a RequiredFieldValidator will be added to the Update page.

However, in some cases there are business rules about the format of data that isn’t supported by the

built-in validation rules. For example, in the Product table, the values saved in the ProductNumber

field all follow a specific format that begins with two uppercase letters followed by a hyphen.

This format can be enforced by decorating the ProductNumber field with a RegularExpression

attribute, as shown in the following code:

c#

[ScaffoldTable(true)]

[MetadataType(typeof(ProductMetadata))]

public partial class Product

{

}

public class ProductMetadata

Customizing the Data Model .

495

{

[RegularExpression(“^[A-Z]{2}-[A-Z0-9]{4}(-[A-Z0-9]{1,2})?$”,

ErrorMessage=”Product Number must be a valid format”)]

public object ProductNumber;

}

Code snippet Product.cs

Vb

<ScaffoldTable(True)> _

<MetadataType(GetType(ProductMetadata))> _

Partial Public Class Product

End Class

Public Class ProductMetadata

<RegularExpression(“^[A-Z]{2}-[A-Z0-9]{4}(-[A-Z0-9]{1,2})?$”, _

ErrorMessage:=”Product Number must be a valid format”)> _

Public ProductNumber As Object

End Class

Code snippet Product.vb

There is also a Range attribute, which is useful for specifying the minimum and maximum allowed

values for a numeric field. Finally, you can apply the Required or StringLength attributes if

you want to enforce these constraints on a field in the data model without specifying them in the

underlying database.

Although useful, the attribute-based validations don’t support all scenarios. For example, a user

could attempt to enter a date for the Product SellEndDate that is earlier than the SellStartDate

value. Due to a database constraint on this field, this would result in a runtime exception rather

than a validation error, which is presented to the user.

For each field that is in the data model, LINQ to SQL defines two methods that are called during an

edit — the OnFieldNameChanging method, which is called just before the field is changed, and the

OnFieldNameChanged method, which is called just after. To handle complex validation rules, you

can complete the appropriate partial method declaration in the data model.

The following code shows a validation rule that ensures a value entered for the Product SellEndDate

field is not earlier than the SellStartDate:

c#

[ScaffoldTable(true)]

[MetadataType(typeof(ProductMetadata))]

public partial class Product

{

partial void OnSellEndDateChanging(DateTime? value)

{

if (value.HasValue && value.Value < this._SellStartDate)

496 .

chaPter 23 dynAmic dATA

{

throw new ValidationException(

“Sell End Date must be later than Sell Start Date”);

}

}

}

Code snippet Product.cs

Vb

<ScaffoldTable(True)> _

<MetadataType(GetType(ProductMetadata))> _

Partial Public Class Product

Private Sub OnSellEndDateChanging(ByVal value As Nullable(Of DateTime))

If value.HasValue AndAlso value.Value < Me._SellStartDate Then

Throw New ValidationException( _

“Sell End Date must be later than Sell Start Date”)

End If

End Sub

End Class

Code snippet Product.vb

Figure 23-7 shows how this custom validation

rule is enforced by Dynamic Data.

customizing the display format

The default way that some of the data types

are formatted is less than ideal. For example,

the Product StandardCost and ListPrice fields,

which use the SQL money data type, are

displayed as numbers to four decimal places.

Also, the Product SellStartDate and SellEndDate

fields, which have a SQL datetime data type,

are formatted showing both the date and time,

even though the time portion is not really useful

information.

The display format of these fields can be

customized in two ways: globally for a specific

data type by customizing the field template; or

on an individual field basis by customizing the

data model. Field template customization is

discussed later in this chapter.

First, to specify how the fields will be formatted in the user interface, decorate the corresponding

property in the data model with the DisplayFormat attribute. This attribute has a DataFormatString

fiGure 23-7

Customizing the Data Model .

497

property that accepts a .NET format string. The attribute also includes a number of additional parameters

to control rendering including the HtmlEncode parameter, which indicates whether the field should

be HTML encoded, and the NullDisplayText attribute, which sets the text to be displayed when the

field ’s value is null. The following code shows how the DisplayFormat attribute can be applied:

c#

[DisplayFormat(DataFormatString="{0:C}")]

public object ListPrice;

[DisplayFormat(DataFormatString="{0:MMM d, yyyy}",

NullDisplayText="Not Specified")]

public object SellEndDate;

Code snippet Product.cs

Vb

< Display(Name:="List Price") > _

< DisplayFormat(DataFormatString:="{0:C}") > _

Public ListPrice As Object

< Display(Name:="Sell End Date") > _

< DisplayFormat(DataFormatString:="{0:MMM d, yyyy}",

NullDisplayText:="Not Specified") > _

Public SellEndDate As Object

Code snippet Product.vb

By default, the display format will only be applied to the Read view. To apply

this formatting to the Edit view set the ApplyFormatInEditMode property to

true on the DisplayFormat attribute.

Second, it’s unlikely that you’ll want to use the database field names in the user interface. It

would be much better to provide descriptive names for all of your fields. You can use the Display

attribute to control how the field labels are rendered. This attribute accepts a number of parameters,

including Name, to specify the actual label and Order to control the order in which fields should be

listed. In the following code, the ProductNumber field has been given a display name of “Product

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页