<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kapok

    垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      455 隨筆 :: 0 文章 :: 76 評論 :: 0 Trackbacks

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpatterns/html/ImpDTOtypedDataSet.asp

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconworkingwithtypeddataset.asp

    Implementing Data Transfer Object in .NET with a Typed DataSet

    ? Data Column: select for more on pattern organization Application Column: select for more on pattern organization Deployment Column: select for more on pattern organization Infrastructure Column: select for more on pattern organization
    Architecture Row: select for more on pattern organization Data Architecture: select for more on pattern organization Application Architecture: select for more on pattern organization Deployment Architecture: select for more on pattern organization Infrastructure Architecture: select for more on pattern organization
    Design Row: select for more on pattern organization Data Design: select for more on pattern organization Application Design: select for more on pattern organization Deployment Design: select for more on pattern organization Infrastructure Design: select for more on pattern organization
    Implementation Row Data Implementation: select for more on pattern organization Application Implementation: select for more on pattern organization Deployment Implementation: select for more on pattern organization Infrastructure Implementation: select for more on pattern organization
    ? Complete List of patterns & practices Complete List of patterns & practices Complete List of patterns & practices Complete List of patterns & practices

    Version 1.0.0

    GotDotNet community for collaboration on this pattern

    Complete List of patterns & practices

    Context

    You are implementing a distributed application with the .NET Framework. The client application displays a form that requires making multiple calls to an ASP.NET Web service to satisfy a single user request. Based on performance measurements you have found that making multiple calls degrades application performance. To increase performance, you would like to retrieve all the data that the user request requires in a single call to the Web service.

    Background

    Note: The following is the same sample application that is described in Implementing Data Transfer Object in .NET with a DataSet.

    The following is a simplified Web application that communicates with an ASP.NET Web service to deliver recording and track information to the user. The Web service in turn calls a database to provide the data that the client requests. The following sequence diagram depicts the interaction among the application, the Web service, and the database for a typical page.

    Figure 1: Behavior of a typical user request

    Figure 1 illustrates the sequence of calls needed to fulfill the entire user request. The first call retrieves the recording information, and the second call retrieves the track information for the specified recording. In addition, the Web service must make separate calls to the database to retrieve the required information.

    Database Schema

    The schema that is used in the example shown in Figure 2 depicts a recording record that has a one-to-many relationship with a track record.

    Figure 2: Schema for sample application

    Implementing a DTO

    One way to improve the performance of this user request is to package all the required data into a data transfer object (DTO) that can be sent with a single call to the Web service. This reduces the overhead associated with two separate calls and allows you to use a single connection with the database to retrieve both the recording and the track information. For a detailed description of how this improves performance, see the Data Transfer Object pattern.

    Implementation Strategy

    A typed DataSet is a generated subclass of System.Data.DataSet. You provide an XML schema file which is then used to generate a strongly-typed wrapper around the DataSet. The following two code samples illustrate the differences. The first sample is implemented with an ordinary DataSet:

     
    
    DataTable dataTable = dataSet.Tables["recording"];
    DataRow row = dataTable.Rows[0];
    string artist = (string)row["artist"];
     

    This sample indicates that you need to know the table and column names to access the tables and fields contained in the DataSet. You also have to know the return type of the Artist field to ensure that the correct cast is done. If you do not use the correct type, you will get a runtime error. The following is the same example implemented with a typed DataSet:

     
    
       Recording recording = typedDataSet.Recordings[0];
       string artist = recording.Artist; 
     

    This example demonstrates the benefits that the typed interface provides. You no longer have to refer to table or column by name and you do not have to know that the return type of the Artist column is a string. A typed DataSet defines a much more explicit interface that is verifiable at compile time instead of at runtime. In addition to the strongly-typed interface a typed DataSet also can be used in all places a DataSet can be used; therefore, it also can be used as a DTO. It is loaded in a similar fashion as a DataSet and it can be serialized to and from XML. In comparison to an ordinary DataSet you do have to write and maintain an XML schema that describes the typed interface. The Microsoft Visual Studio .NET development system provides a number of tools that simplify the creation and maintenance of the schema.The rest of this implementation strategy outlines the steps required in creating a typed DataSet for the sample application just described.

    Creating a Typed DataSet

    A typed DataSet is generated from an XML schema. Visual Studio .NET provides a drag-and-drop tool which automates the creation of the schema (see Figure 3) and the generation of the typed DataSet classes. If you do not use Visual Studio.NET, you can write the XML schema and use a command-line tool called XSD.exe to generate the typed DataSet. For detailed instructions on both of these methods, see "Typed DataSets in ADO.NET" from the May 2001 issue of .NET Developer [Wildermuth02].

    Figure 3: Visual Studio .NET DataSet file type

    RecordingDto.xsd

    The following is the XML schema for the DTO to be used in this example. It combines both the recording table along with its associated track records in a single typed DataSet named RecordingDto:

     
    
    <?xml version="1.0" encoding="utf-8" ?>
    <xs:schema id="RecordingDto" targetNamespace="http://msdn.microsoft.com/practices/RecordingDto.xsd"
       elementFormDefault="qualified" attributeFormDefault="qualified" xmlns="http://tempuri.org/RecordingDTO.xsd"
       xmlns:mstns="http://msdn.microsoft.com/practices/RecordingDto.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:codegen="urn:schemas-microsoft-com:xml-msprop">
       <xs:element name="RecordingDto" msdata:IsDataSet="true">
          <xs:complexType>
             <xs:choice maxOccurs="unbounded">
                <xs:element name="recording" codegen:typedName="Recording" codegen:typedPlural="Recordings"
                   codegen:typedChildren="Track">
                   <xs:complexType>
                      <xs:sequence>
                         <xs:element name="id" type="xs:long" codegen:typedName="Id" />
                         <xs:element name="title" type="xs:string" codegen:typedName="Title" />
                         <xs:element name="artist" type="xs:string" codegen:typedName="Artist" />
                      </xs:sequence>
                   </xs:complexType>
                </xs:element>
                <xs:element name="track" codegen:typedName="Track" codegen:typedPlural="Tracks" codegen:typedParent="Recording">
                   <xs:complexType>
                      <xs:sequence>
                         <xs:element name="id" type="xs:long" codegen:typedName="Id" />
                         <xs:element name="title" type="xs:string" codegen:typedName="Title" />
                         <xs:element name="duration" type="xs:string" codegen:typedName="Duration" />
                         <xs:element name="recordingId" type="xs:long" codegen:typedName="RecordingId" />
                      </xs:sequence>
                   </xs:complexType>
                </xs:element>
             </xs:choice>
          </xs:complexType>
          <xs:unique name="RecordingDTOKey1" msdata:PrimaryKey="true">
             <xs:selector xpath=".//mstns:recording" />
             <xs:field xpath="mstns:id" />
          </xs:unique>
          <xs:unique name="RecordingDTOKey2" msdata:PrimaryKey="true">
             <xs:selector xpath=".//mstns:track" />
             <xs:field xpath="mstns:id" />
          </xs:unique>
          <xs:keyref name="recordingtrack" refer="mstns:RecordingDTOKey1">
             <xs:selector xpath=".//mstns:track" />
             <xs:field xpath="mstns:recordingId" />
          </xs:keyref>
       </xs:element>
    </xs:schema>
     

    This schema is not the exact file produced by Visual Studio .NET. It is annotated with a number of attributes that are prefixed from the codegen namespace. This modification is desirable because the code that is generated does not adhere to the .NET naming conventions. For example, without the modification, Visual Studio .NET would generate a track class that corresponds to the track table, whereas according to conventions used in the .NET Framework the class should be named Track. To change the name of the class that is generated, you must add the codegen:typedName attribute to the element definition in the XML schema:

     
    
    <xs:element name="track" codegen:typedName="Track">
       
    </element>
     

    There are a number of other attributes besides codegen:typedName. For a detailed description of all the attributes, see "Typed DataSets in ADO.NET" from the May 2001 issue of .NET Developer [Wildermuth02].

    Filling a Typed DataSet from the Database

    The following code example demonstrates how to fill a typed DataSet with the data that the sample application requires. This includes the specific recording record and all of its associated track records. The difference between this code and filling an ordinary DataSet is that you do not need to explicitly define the relationship between the recording and track records.

    Assembler.cs

    Just as in Implementing a Data Transfer Object in .NET with a DataSet, an Assembler class maps the actual database calls into the typed DataSet:

     
    
    using System;
    using System.Data;
    using System.Data.SqlClient;
    
    using Recording;
    
    public class Assembler
    {
       public static RecordingDto CreateRecordingDto(long id)
       {
          string selectCmd = 
             String.Format(
             "select * from recording where id = {0}",
             id);
    
          SqlConnection myConnection = 
             new SqlConnection(
             "server=(local);database=recordings;Trusted_Connection=yes;");
          SqlDataAdapter myCommand = new SqlDataAdapter(selectCmd, 
             myConnection);
    
          RecordingDto dto = new RecordingDto();
          myCommand.Fill(dto, "recording");
    
          String trackSelect = 
             String.Format(
             "select * from Track where recordingId = {0} order by Id",
             id);
    
          SqlDataAdapter trackCommand = 
             new SqlDataAdapter(trackSelect, myConnection);
          trackCommand.Fill(dto, "track");
    
          return dto;
       }
    }
     

    Note: The example shown here is not meant to describe the only way to fill the typed DataSet. There are many ways to retrieve this data from the database. For example, you could use a stored procedure.

    Using a Typed DataSet in an ASP.NET Page

    As mentioned previously, a typed DataSet inherits from System.Data.DataSet. This means that it can be substituted for a DataSet. For example, when using the .NET user interface controls (Web Forms or Windows Forms) a typed DataSet can be used in all places you could use a DataSet. The sample application page shown in the following code example uses two DataGrid controls, RecordingGrid and TrackGrid. You can use the typed DataSet, RecordingDto when setting the DataSource properties on the controls because a typed DataSet inherits from DataSet.

     
    
    using System;
    using System.Data;
    using RecordingApplication.localhost;
    
    public class RetrieveForm : System.Web.UI.Page
    {
       private RecordingCatalog catalog = new RecordingCatalog();
     
       // 
    
       protected void Button1_Click(object sender, System.EventArgs e)
       {
          string stringId = TextBox1.Text;
          long id = Convert.ToInt64(stringId);
    
          RecordingDTO dto = catalog.Get(id);
          RecordingGrid.DataSource = dto.recording;
          RecordingGrid.DataBind();
    
          TrackGrid.DataSource = dto.track;
          TrackGrid.DataBind();
       }
    }
     

    Tests

    Because the typed DataSet is generated by tools in the .NET Framework, you do not need to write tests to verify that it functions correctly. In the following tests, you are testing that the Assembler class loaded the typed DataSet correctly.

    AssemblerFixture.cs

     
    
    using NUnit.Framework;
    using System.Data;
    using Recording;
    
    [TestFixture]
    public class AssemblerFixture
    {
       private RecordingDto dto;
       private RecordingDto.Recording recording;
       private RecordingDto.Track[] tracks; 
       
       [SetUp]
       public void Init()
       {
          dto = Assembler.CreateRecordingDto(1234);
          recording = dto.Recordings[0];
          tracks = recording.GetTracks();
       }
    
       [Test]
       public void RecordingCount()
       {
          Assert.Equals(1, dto.Recordings.Rows.Count);
       }
    
       [Test]
       public void RecordingTitle()
       {
          Assert.Equals("Up", recording.Title.Trim());
       }
    
    
       [Test]
       public void RecordingChild()
       {
          Assert.Equals(10, tracks.Length);
    
          foreach(RecordingDto.Track track in tracks)
          {
             Assert.Equals(recording.Id, track.RecordingId);
          }
       }
    
       [Test]
       public void TrackParent()
       {
          RecordingDto.Track track = tracks[0];
          RecordingDto.Recording parent = track.Recording;
          Assert.Equals("Up", parent.Title.Trim());
       }
    
       [Test]
       public void TrackContent()
       {
          RecordingDto.Track track = tracks[0];
          Assert.Equals("Darkness", track.Title.Trim());
       }
    
       [Test]
       public void InvalidRecording()
       {
          RecordingDto dto = Assembler.CreateRecordingDto(-1);
          Assert.Equals(0, dto.Recordings.Rows.Count);
          Assert.Equals(0, dto.Tracks.Rows.Count);
       }
    }
     

    These tests describe how to access the individual elements of the DataSet. Because of the use of a typed DataSet, the test code does not require the actual column names and does not require the return type to be cast. Comparing these tests with the ones described in Implementing Data Transfer Object in .NET with a DataSet reveals the differences between using a strongly-typed interface and a generic interface. The strongly-typed interface is easier to use and understand. It also provides the added benefit of compile-time checking on return types.

    Resulting Context

    Implementing DTO with a typed DataSet shares a number of the same benefits and liabilities as implementing DTO with a DataSet; however, certain benefits and liabilities are unique to a typed-DataSet implementation.

    Benefits

    The typed DataSet shares the following benefits with a DataSet when used as a DTO:

  • Development tool support. Because the DataSet class is implemented in ADO.NET, there is no need to design and implement the DTO. There is also extensive support in Visual Studio for automating the creation and filling of DataSet and typed-DataSet objects.

  • Integration with controls. A DataSet works directly with the built-in controls in Windows Forms and Web Forms, making it a logical choice as a DTO.

  • Serialization. The DataSet comes complete with the ability to serialize itself into XML. Not only is the content serialized, but the schema for the content is also present in the serialization.

  • Disconnected database model. The DataSet represents a snapshot of the current contents of the database. This means that you can alter the contents of the DataSet and subsequently use the DataSet as the means to update the database.

  • An additional benefit that might persuade you to use a typed DataSet as opposed to an ordinary DataSet is the strongly-typed interface of the typed DataSet. A typed DataSet, as described here, generates classes that can be used to access the contained data. The classes present an interface which defines how the class is to be used in a more explicit manner. This removes the need for casting which was present in the DataSet implementation.

    Liabilities

    The typed DataSet shares the following liabilities with a DataSet when used in the context of a DTO:

  • Interoperability. Because the DataSet class is part of ADO.NET, it is not the best choice for a DTO in cases requiring interoperability with clients that are not running the .NET Framework.. You can still use DataSet, however, the client will be forced to parse the XML and build its own representation. If interoperability is a requirement, see Implementing Data Transfer Object in .NET with Serialized Objects.

  • Stale data. The typed DataSet, like a DataSet, is disconnected from the database. It is filled with a snapshot of the data in the database when it is constructed. This implies that the actual data in the database may be different from what is contained in the typed DataSet. For reading primarily static data, this is not a major issue. If the data is constantly changing, however, using any kind of DataSet is not recommended.

  • Potential for performance degradation. Instantiating and filling a DataSet can be an expensive operation. Serializing and deserializing a DataSet can also be very time consuming. A good rule of thumb for using a DataSet is that a DataSet is a good choice when you are using more than one table or relying on the capability of the DataSet to update the database. If you are displaying the results from a single table, then using a DataReader with strongly-typed objects may offer better performance. For more information, see Implementing Data Transfer Object in .NET with Serialized Objects.

  • The following are additional liabilities when using a typed DataSet as opposed to an ordinary DataSet:

  • A typed DataSet is still a DataSet. A typed DataSet can be substituted at runtime with a DataSet. This means that even though the strongly-typed interface exists, programmers can still access the data without the typed interface. A possible result of doing this is that there could be parts of the code which couple the application tightly to the DataSet table and column names.

  • The need for an XML schema. When using a typed DataSet you have to create and maintain an XML schema to describe the strongly-typed interface. Visual Studio .NET provides a number of tools to assist in this process, but nevertheless you still have to maintain an additional file.

    Related Patterns

    For more information, see the following related patterns:

  • Implementing Data Transfer Object in .NET with a DataSet.

  • Implementing Data Transfer Object in .NET with Serialized Objects.

  • Assembler. In Enterprise Application Architecture Patterns, Fowler defines Assembler as a specialized instance of the Mapper pattern [Fowler03].

    Acknowledgments

    [Beau02] Beauchemin, Bob. Essential ADO.NET. Addison-Wesley, 2002.

    [Fowler03] Fowler, Martin. Enterprise Application Architecture Patterns. Addison-Wesley, 2003.

    [Wildermuth01] Wildermuth, Shawn. "Typed DataSets in ADO.NET." .NET Developer. May 2001.

    Patterns Practices

  • posted on 2005-04-12 12:49 笨笨 閱讀(478) 評論(0)  編輯  收藏 所屬分類: ALL程序員生活.NET個人項目所需資料
    主站蜘蛛池模板: 亚洲男女性高爱潮网站| 国产高清免费的视频| 国产亚洲综合色就色| 中文无码日韩欧免费视频| 亚洲一区无码精品色| 久久九九久精品国产免费直播| 亚洲人成无码久久电影网站| 特级毛片免费播放| 亚洲国产精品无码久久青草| 二个人看的www免费视频| 亚洲线精品一区二区三区| 在线观看免费黄网站| 亚洲AV成人精品网站在线播放| 你懂得的在线观看免费视频| 亚洲av无码精品网站| 亚洲精品国精品久久99热一| 一个人免费视频在线观看www | 四虎精品视频在线永久免费观看| 久久综合九九亚洲一区| 久久免费观看国产精品| 亚洲国产美女精品久久| 韩国18福利视频免费观看| 一二三四在线观看免费中文在线观看| 中文字幕亚洲天堂| 99re免费视频| 亚洲午夜无码久久久久小说 | 亚洲视频在线观看免费| 亚洲欧洲日产专区| 国产精品深夜福利免费观看| 人成电影网在线观看免费| 亚洲电影一区二区| 国产一精品一AV一免费孕妇| 日韩在线一区二区三区免费视频| 亚洲成AV人片在线观看无码| 久久笫一福利免费导航| 有色视频在线观看免费高清在线直播 | 亚洲人成网站在线观看播放动漫| 午夜dj免费在线观看| 中文字幕免费在线看线人动作大片 | 国产极品粉嫩泬免费观看| 国产在线精品一区免费香蕉|