asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search





Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Designing N-Tiered Data Access Layer Using Datasets - Part 4
By David Catherman
Rating: 3.5 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article



  • download source code
  • Part 4 - Adding Special Table Adapter Queries

    Introduction

    Part of the business logic encapsulated in the Typed DataSet is the ability to add specialized queries to the table adapters to retrieve the data with different filters. By manipulating the XML schema that defines the dataset and adding the correct XML metadata, Visual Studio will generate the added queries for us. In this article, filtering queries will be automatically added to each table adapter for each field that is indexed on the table in the database.

    Review

    Part 1 of this article covered the basics of the Typed DataSet in Visual Studio 2005/8, including a quick tutorial on how to use the visual editor/wizards and a review of the functionality of the code it generates.

    Part 2 showed how to add the missing methods to wrap the table adapter methods to provide tier separation.

    Part 3 demonstrated a code generation system to automatically create the missing code.

    Note: I have updated the code download so that the CodeGen system will generate C# code as well as VB.NET and includes the table adapter modifications in this article.

    Table Adapter Special Queries

    In part 1 of this article series, the Table Adapters were produced by the DataSet Generator. When using the wizard to add a table to the dataset editor, a default query was generated to retrieve all data in the table either by filling an existing table or returning the table as an object (Get Data). This default table adapter should be left as generic (no where clause) for updateable tables. If the table is a read-only, the primary query can be filtered as necessary, but if the table needs updating, then leave the default query to retrieve all records so the update command can be generated.

    If you need to restrict or filter the data retrieved, add a special query to the table adapter. The DataSet Designer allows multiple queries to be added for each table adapter and it will generate the appropriate methods. These additional queries will not affect the update commands.

    The following walk through will demonstrate the principle being discussed. Start with Visual Studio 2005 (or 2008) and the dataset created in previous articles based on the Northwind Orders table. Open the OrdersDataSet in the Visual Editor and notice the Table Adapter (lower bar in the table representation). Select the Table Adapter bar and look at the properties.

    This series of articles is about maintaining a clean tier separation in an application. There are two properties that should be changed to support this tier separation: The access Modifier should be changed from Public to Friend (Internal in C#); and the GenerateDBDirectMethods should be changed to False. Changing the access modifier to non-public will restrict access to the table adapters from the presentation layer. In the scenario of this article, the table adapters should only be accessible from the dataset that generated them in order to enforce the business rules of the middle tier.

    The GenerateDBDirectMethods property when true will generate the public methods for Select, Insert, Updated, and Delete, but using these methods is discouraged since they bypass the business tier and encourage client-server access. If you have ever used the ObjectDataSource in ASP.NET, it is designed to access these methods by default, but again, this violates n-tiered architecture rules. (A better way to work with the ObjectDataSouce will be discussed in part 5 of these articles.) Changing this property to false stops Visual Studio from needlessly generating these methods since they would not be accessible due to the access modifier change.

    Adding a Filter Query Manually

    Visual Studio has a great tool to edit and add the queries to a table adapter. With the Visual DataSet Editor open to the dataset from the NorthWind database used in the earlier articles, right-click the OrdersTableAdapter bar and select the Add Query option from the context menu.

    Like the Dataset Configure wizard, the Query Configuration Wizard gives the option for using embedded SQL or using stored procedures. If the stored procedures do not already exist, the wizard will generate them for you. For this tutorial, select "Use SQL statements".

    The next screen presents the Table Adapter Query Configuration Wizard.

    The other options might be useful in future articles, but for now, the query will return a filtered version of the same dataset table, so select the first Select option.

    Enter the SQL statement where clause desired or use the Query Builder to design the query visually as shown below.

    Add the parameter @CustomerID to the Filter for the CustomerID column which adds a Where clause to the query. Click the Execute Query button to test the SQL and see the resuls.

    Click OK to close the Query Builder and then click Next on the previous screen (notice that the query has added the Where clause).

    The Wizard gives the default name for the query of "FillBy"—modify the names by adding "CustomerID" on both the Fill a Data Table and Return a Data Table commands.

    The last screen shows a summary of what the wizard accomplished. Click Finish to complete the task.

    Back in the DataSet designer, the Table Adapter has a new line added to it to show the added query. When calling the table adapter, this query can be used to retrieve just the records for a specific customer.

    The query can be as complicated as necessary, but for best performance the columns that are parameterized should be indexed in the database. Since there is a relationship with the Customer table, the foreign key of CustomerID should be indexed.

    Automating the Filtering Queries

    This method of adding queries is powerful, but time consuming. So here is the purpose of this article--wouldn't it be nice to have the queries generated automatically? It took a few tricks, but here is how it happens.

    First, decide which fields need filtering queries added. The automated process looks into the metadata of the database and finds all the indexed fields and adds queries to the table adapter for each. This list will include all of the foreign keys and any other fields that have indexes in the database. Currently, only single field indexes are added, but the procedure could be expanded to include multi-field indexes.

    A Look at What Was Generated

    When the above wizard completed, it generated a new method on the Table Adapter. Looking at the Object Browser shows the signature of the method.

    The code that was generated is straight forward, but references the command array, so modifying this code directly would require making changes to generated code and would be written over the next time the dataset was generated.

    <Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
     Global.System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter"), _
     Global.System.ComponentModel.DataObjectMethodAttribute(Global.System.ComponentModel.DataObjectMethodType.Fill, false)> _
        Public Overloads Overridable Function FillByCustomerID(ByVal dataTable As NorthwindDataSet.OrdersDataTable, ByVal CustomerID As String) As Integer
            Me.Adapter.SelectCommand = Me.CommandCollection(1)
            If (CustomerID Is Nothing) Then
                Me.Adapter.SelectCommand.Parameters(0).Value = Global.System.DBNull.Value
            Else
                Me.Adapter.SelectCommand.Parameters(0).Value = CType(CustomerID,String)
            End If
            If (Me.ClearBeforeFill = true) Then
                dataTable.Clear
            End If
            Dim returnValue As Integer = Me.Adapter.Fill(dataTable)
            Return returnValue
        End Function

    Modifying the XML Schema for the DataSet

    Another approach to automatically add the filtering queries is to modify the XML that defines the dataset and let Visual Studio generate the methods. This requires some manipulation of XML, but additions are preserved.

    Datasets are stored in XML format and converted to a visual format by the Dataset Editor. Now we need to see the raw XML behind the dataset so, right click on the .XSD file and select "Open With..." and "XML Editor" to examine the XML and see how the file is constructed. The first part of the file is the table adapters and the second half is the dataset. Of particular interest here is the section <Sources> (under the table adapters).

    For each additional query there is a DbSource, DbCommand, and Parameter section. To automatically build the queries in the dataset, these sections need to be created from the metadata.

    What Queries Need To Be Generated?

    The first step is to build a list of the fields for which to create queries. The query pulls from the system tables to list the foreign key and indexed fields. (This should be updated to use the metadata functions, but it is something I pulled out of an old app and it works.) Here is how to pull it together.

    1. Add a new dataset to the CodeGen project and name it IndexDataSet.

    2. Drag and drop any table on to it (it doesn't matter which one) to create the table adapter.

    3. Right click configure the table and substitute the following SQL.

       SELECT DISTINCT
                   SO.name AS TableName, SC.name AS FieldName, ST.name + CASE WHEN sc.length <> st.length THEN '(' + CONVERT(varchar, sc.length)
                   + ')' ELSE '' END AS DataTypeLong, ST.name AS DataType, '' AS NetDataType
       FROM        sys.systypes AS ST INNER JOIN
                   sys.syscolumns AS SC INNER JOIN
                   sys.sysobjects AS SO ON SC.id = SO.id ON ST.xtype = SC.xtype LEFT OUTER JOIN
                   sys.sysforeignkeys AS FK ON SC.id = FK.fkeyid AND SC.colid = FK.fkey LEFT OUTER JOIN
                   sys.sysindexkeys AS SIK INNER JOIN
                   sys.sysindexes AS SI ON SIK.indid = SI.indid AND SIK.id = SI.id ON SO.id = SI.id AND SC.colid = SIK.colid AND SC.id = SIK.id
       WHERE        (SO.xtype = 'U') AND (SIK.keyno IS NOT NULL) AND (SC.name IS NOT NULL) AND
                   (SI.status / 2048 & 1 = 0) OR (SO.xtype = 'U') AND (FK.constid IS NOT NULL)
       ORDER BY    TableName, FieldName

      (Note: For SQL Server 2000, you may need to remove the "sys." schema in this code)

    4. Complete the wizard and then change the name of the table to sys_IndexList (in keeping with the naming scheme of the metadata tables).

    5. In the code behind for the dataset (right click, view code), add a method that will accept a connection string for the database to read the metadata from:

       Partial Class IndexDataSet
           Shared taIndexList As New IndexDataSetTableAdapters.sys_IndexListTableAdapter

           Partial Public Class sys_IndexListDataTable
               Public Sub Fill(Optional ByVal ConString As String = "")
                   If ConString.length > 0 Then
                       taIndexList.Connection.ConnectionString = ConString
                   End If
                   taIndexList.Fill(Me)
               End Sub
           End Class

       End Class

    6. Save and close the dataset

    This dataset will be used in the code to return a list of tables and indexed fields.

    For the front-end to select the dataset and launch the program, the form created in the previous articles can be used (see below). OK, it has been improved a bit--the new version is available in the related code download.

    The "Add Index Queries to Dataset" button has been added to call the code. The code behind the button is as follows:

    Private Sub AddQueryButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddQueryButton.Click
        If ListBox1.SelectedItem IsNot Nothing Then
            'find the document file for the dataset
            Dim dir As String = Me.TextBox1.Text.Substring(0, Me.TextBox1.Text.LastIndexOf("\Debug\") - 3) 'get rid of the bin or obj
            Dim file As String = dir & ListBox1.SelectedItem & ".xsd"
            If Not My.Computer.FileSystem.FileExists(file) Then
                Me.OpenFileDialog1.FileName = ""
                Me.OpenFileDialog1.InitialDirectory = file
                Me.OpenFileDialog1.DefaultExt = ".xsd"
                Me.OpenFileDialog1.Title = "Identify the XSD file for the dataset"
                Me.OpenFileDialog1.ShowDialog()
                file = Me.OpenFileDialog1.FileName
                Me.OpenFileDialog1.Dispose()
            End If
            DataSetEdit.TableAdapterUpdate(file)
        End If
    End Sub

    This code assumes the form has already identified the project that the dataset is in and also that the file was opened from the Debug directory. The code tries to put together the filename and if it can't, opens the file dialog to get the filename from the user.

    Editing the XML

    The XML namespace has many tools to help manipulate an XML file. One problem that I ran into is that the dataset .XSD file has a combination of elements, some that use a namespace prefix and some that don't. This causes a problem with the XPath function. I spent almost a day trying to make it work including defining a default namespace. I ended up skipping the XPath search and using the Document Object Model (DOM) functions. It requires more code to walk the node tree, but does work.

    Let's get started putting the code together. Start by adding a new Class Library to the project named DatasetEdit.vb. Add a shared method named TableAdapterUpdate with the file name passed in as a parameter.

        Public Shared Sub TableAdapterUpdate(ByVal dsFileName As String)
            Dim saveFlag As Boolean = False
            Dim xdoc As New System.Xml.XmlDocument

    Load the XML file into the DOM. Defining the namespace is probably not important since the XPath function is not used, but the technique could be helpful to someone.

            xdoc.Load(dsFileName)
            'set up the namespace manager
            Dim man As New XmlNamespaceManager(xdoc.NameTable)
            man.AddNamespace("xs", "http://www.w3.org/2001/XMLSchema")
            Dim schema As XmlNode = xdoc.SelectSingleNode("xs:schema", man)
            man.AddNamespace("ns", schema.Attributes("xmlns").Value)
            man.AddNamespace("msprop", schema.Attributes("xmlns:msdata").Value)
            man.AddNamespace("msdata", schema.Attributes("xmlns:msprop").Value)

    Load the dataset with the indexed fields from the proper database. Look at the table adapter and glean the connection name and then get the connection string from settings.

            'get the indexes
            Dim ds As New IndexDataSet
            'get the connection ref of the first table adapter
            Dim conString As String = ""
            Dim conName As String = root.Item("DataSource").Item("Tables").FirstChild.Item("MainSource").Item("DbSource").Attributes("ConnectionRef").Value
            'get the connection string from the settings ref
            For Each conNode As XmlNode In root.Item("DataSource").Item("Connections")
                If conNode.Attributes("Name").Value = conName Then
                    conString = System.Configuration.ConfigurationManager.ConnectionStrings("WinMetadata.My.MySettings." & conNode.Attributes("AppSettingsPropertyName").Value).ConnectionString
                    Exit For
                End If
            Next
            If conString.Length > 0 Then 'if specific connection string found, use it
                ds.sys_IndexList.Fill(conString)
            Else
                ds.sys_IndexList.Fill()
            End If

    In this case, the root node we will work with is the one that contains the table adapters. Looping through each node in the root will allow each table adapter to be processed.

            Dim sourcesNode As XmlNode, taName As String, dsFillName As String
            Dim root As XmlNode = xdoc.SelectSingleNode("xs:schema/xs:annotation/xs:appinfo", man)
            For Each taNode As XmlNode In root.Item("DataSource").Item("Tables").ChildNodes

    The queries are stored in a node called <Sources> under the table adapter. Each child node features a filtering query. The For loop makes a delimited list of the names of the fill methods that already exist so they are preserved and not overwritten or duplicated.

                taName = taNode.Attributes("Name").Value
                sourcesNode = taNode.Item("Sources")
                'Get a list of the existing queries
                Dim existingList As String = ""
                For Each dsNode As XmlNode In sourcesNode.ChildNodes
                    dsFillName = dsNode.Attributes("FillMethodName").Value
                    existingList += dsFillName & ","
                Next
                'add a source for each index field
                For Each fld As IndexDataSet.sys_IndexListRow In ds.sys_IndexList.Select("TableName='" & taName & "'")
                    'skip if the query already exist
                    If existingList.IndexOf("FillBy" & fld.FieldName) = -1 Then
                        'add the query to the adapter
                        Dim newNode As XmlNode = CreateIndexNode(xdoc, taNode, taName, fld.FieldName, fld.DataType, fld.NetDataType)
                        sourcesNode.AppendChild(newNode)
                        saveFlag = True
                    End If
                Next
            Next
            If saveFlag Then
                xdoc.Save(dsFileName)

    I made an effort to automatically run the command line XSD generator to build the code, but was never successful. If anyone can get this working, let me know.

                ''generate DataSet designer class using XSD.exe tool
                'Dim proc As New System.Diagnostics.Process()
                'proc.EnableRaisingEvents = False
                'proc.StartInfo.UseShellExecute = False
                'proc.StartInfo.RedirectStandardOutput = True
                'proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden
                'proc.StartInfo.WorkingDirectory = dsFileName.Substring(0, dsFileName.LastIndexOf("\"))
                'proc.StartInfo.FileName = "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\xsd.exe"
                'proc.StartInfo.Arguments = dsFileName + " /dataset /o:" + dsFileName.Substring(0, dsFileName.LastIndexOf("\")) ' /namespace:" + Settings.Default.Namespace
                'proc.Start()
                'proc.WaitForExit(60000)
                'proc.StartInfo.FileName = "C:\Windows\System32\xcopy.exe"
                'proc.StartInfo.Arguments = dsFileName.Substring(0, dsFileName.LastIndexOf(".")) & " "

    It turns out that running the command line generator is not necessary. In Visual Studio the generate can be forced by right clicking on the XSD file in Solutions Explorer and selecting "Run Custom Tool". Here is the end of the method:

                MessageBox.Show("Queries Added to XSD. Open the DataSet in Visual Studio and reconfigure each table to build the added queries.")
            End If
        End Sub

    This leaves the code for the CreateIndexNode Function called from the code above. This section of code manipulates XML nodes and creates a new set of nodes for the query.

        Shared Function CreateIndexNode(ByRef xdoc As XmlDocument, ByVal taNode As XmlNode, ByVal taName As String, ByVal fldName As String, ByVal fldType As String, ByVal fldTypeNet As String)
            Dim dbNode As XmlNode, selNode As XmlNode, insNode As XmlNode, parNode As XmlNode, attr As XmlAttribute
            'get the dbsource node for the table
            dbNode = taNode.Item("MainSource").Item("DbSource")
            If dbNode IsNot Nothing Then
                'use the existing DbSource node for the table as a model
                Dim newNode As XmlNode = dbNode.CloneNode(True)
                'get rid of the modify commands, leaving only the select command
                If newNode.Item("DeleteCommand") IsNot Nothing Then newNode.RemoveChild(newNode.Item("DeleteCommand"))
                If newNode.Item("UpdateCommand") IsNot Nothing Then newNode.RemoveChild(newNode.Item("UpdateCommand"))
                'chang the names of the methods
                newNode.Attributes("FillMethodName").Value = "FillBy" & fldName
                newNode.Attributes("GeneratorSourceName").Value = "FillBy" & fldName
                newNode.Attributes("UserSourceName").Value = "FillBy" & fldName
                newNode.Attributes("GetMethodName").Value = "GetDataBy" & fldName
                newNode.Attributes("GeneratorGetMethodName").Value = "GetDataBy" & fldName
                newNode.Attributes("UserGetMethodName").Value = "GetDataBy" & fldName
                parNode = Nothing
                insNode = newNode.Item("InsertCommand")
                If insNode Is Nothing Then
                    'TODO - if there is no insert command, then generate the parameter node
                    'get the Insert command node
                    If insNode.Item("DbCommand").Attributes("CommandType").Value = "StoredProcedure" Then
                        'TODO check for command type as stored procedure - change accordingly
                    End If
                Else
                    'find the parameter for the indexed field (search through each since xpath does not work)
                    For Each xNode As XmlNode In insNode.Item("DbCommand").Item("Parameters").ChildNodes
                        If xNode.Attributes("SourceColumn").Value = fldName Then
                            parNode = xNode.CloneNode(True)
                            Exit For
                        End If
                    Next
                End If
                If parNode IsNot Nothing Then
                    parNode.Attributes("AutogeneratedName").Value = fldName
                    parNode.Attributes("ParameterName").Value = fldName
                    'add 'ColumnName' attribute
                    attr = xdoc.CreateAttribute("ColumnName")
                    attr.Value = fldName
                    parNode.Attributes.SetNamedItem(attr)
                Else
                    'need to construct the parameter node
                    parNode = xdoc.CreateNode(XmlNodeType.Element, "", "Parameter", "")
                    attr = xdoc.CreateAttribute("AllowDbNull")
                    attr.Value = "False"
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("AutogeneratedName")
                    attr.Value = fldName
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("DataSourceName")
                    attr.Value = fldName
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("DbType")
                    attr.Value = fldTypeNet
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("Direction")
                    attr.Value = "Input"
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("ParameterName")
                    attr.Value = "@" + fldName
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("ProviderType")
                    attr.Value = fldType
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("SourceColumn")
                    attr.Value = fldName
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("SourceColumnNullMapping")
                    attr.Value = "False"
                    parNode.Attributes.SetNamedItem(attr)
                    attr = xdoc.CreateAttribute("SourceVersion")
                    attr.Value = "Current"
                    parNode.Attributes.SetNamedItem(attr)
                End If
                'get the select command node
                selNode = newNode.Item("SelectCommand")
                Dim comText As String = selNode.Item("DbCommand").Item("CommandText").InnerText
                'is there already a where clause?
                If comText.IndexOf(" Where ") > 0 Then
                    comText += " AND " 'This assumes Where is last clause -- no group by
                Else 'add the where clause
                    comText += " Where "
                End If
                comText += fldName & " = @" & fldName
                'replace the command text
                selNode.Item("DbCommand").Item("CommandText").InnerText = comText
                'add the parameter node
                'TODO: if stored procedure type, need to add a ReturnValue parameter
                selNode.Item("DbCommand").Item("Parameters").AppendChild(parNode)

                'get rid of the insert command
                newNode.RemoveChild(newNode.Item("InsertCommand"))
                Return newNode
            Else
                Return Nothing
            End If
    End Function

    This is a lot of code to browse through, but hopefully there are enough comments to explain what is happening.

    Running the Code

    Now run the code to get the Dataset Select form. Select the assembly for the project and then select the Northwind Orders dataset. Click the "Add Index Queries to Dataset" button to run the code. The code should run very quickly.

    After closing the application, go back to the Northwind Orders dataset. In order to see the new queries, force Visual Studio to rebuild the tables by right clicking on each table and select "Configure". Just click "Finish" on the wizard to force rebuilding. The new queries should show in the table adapter section (Orders has a lot of indexed fields).

    Note: After messing with the XML behind the dataset, you may need to manually regenerate the designer code. When viewing the dataset in the Solution explorer with "Show All Files" turned on (icon button at the top of the Solution Explorer) and you don't see the DatasetName.designer.vb (or .cs) file then right-click on the dataset main .XSD file and select "Run Custom Tool". This will force the Visual Studio code generator to run. (The DataSet Visual Editor must be closed to run this tool.)

    Using the Generated Functions

    The code generator from part 3 of this article series will generate wrappers for all of the new queries when you click the other "Generate" buttons on the form. In your presentation logic, when you need to fill a data table, you should have "FillBy…" functions for each indexed field in the database to choose from.

    Conclusion

    This article is a continuing explanation of my vision of using rapid application development tools available in Visual Studio to speed development without sacrificing architectural principles. The code generator is continuing to expand and is becoming a primary part of the architecture. The addition of specific queries for the indexed fields is a small part, but does add functionality that is sometimes needed.

    The code generator has evolved to the point that it needs some reorganization and solidifying. Up to this point, the metadata used in code generation has been gleaned from the assembly using reflection. In future articles, I will add a metadata system to store the metadata and show how metadata can be used more in code generation.

    If you find this article series helpful or have questions, please contact me at the address below.

    About the Author

    David Catherman

    Email: David (dot) Catherman (at) Hotmail (dot) com

    David Catherman has 20+ years designing and developing database applications with specific concentration for the last 6-7 years on Microsoft .NET and SQL Server. He is currently working as an Application Architect and Senior Developer using Visual Studio 2005 and SQL Server 2005 (moving on to 2008). He has several MCPs in .NET and is pursuing MCSD.

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Other Articles
    Jul 21, 2005 - N-Tier Web Applications using ASP.NET 2.0 and SQL Server 2005 - Part 1
    While the .NET Framework made building ASP.NET applications easier then it had ever been in the past, .NET 2.0 builds on that foundation in order to take things to the next level. This article shows you to how to construct an N-Tier ASP.NET 2.0 Web application by leveraging the new features of ASP.NET 2.0 and SQL Server 2005.
    [Read This Article]  [Top]
    Apr 28, 2005 - New Files and Folders in ASP.NET 2.0
    With the release of ASP.NET 2.0, Microsoft has greatly increased the power of ASP.NET by introducing a suite of new features and functionalities. As part of this release, ASP.NET 2.0 also comes with a host of new special files and folders that are meant to be used to implement a specific functionality. This article examines these new files and folders in detail and provides examples that demonstrate how to utilize them to create ASP.NET 2.0 applications.
    [Read This Article]  [Top]
    Mar 10, 2005 - The DataSet Grows Up in ADO.NET 2.0 - Part 2, Cont'd
    Alex Homer continues his detailed look at the major changes to the DataSet class. In this part, he looks at two features that allow developers to work with data in a more structured and efficient way when using the DataSet with a SQL Server 2005 database server.
    [Read This Article]  [Top]
    Mar 9, 2005 - The DataSet Grows Up in ADO.NET 2.0 - Part 2
    Alex Homer continues his detailed look at the major changes to the DataSet class. In this part, he looks at two features that allow developers to work with data in a more structured and efficient way when using the DataSet with a SQL Server 2005 database server.
    [Read This Article]  [Top]
    Mar 3, 2005 - The DataSet Grows Up in ADO.NET 2.0 - Part 1, Cont'd
    In this article, Alex Homer looks at the changes between the version 1.x and version 2.0 DataSet and their associated classes, showing you how you can take advantage of the new features to improve your applications' capabilities and performance.
    [Read This Article]  [Top]
    Mar 2, 2005 - The DataSet Grows Up in ADO.NET 2.0 - Part 1
    In this article, Alex Homer looks at the changes between the version 1.x and version 2.0 DataSet and their associated classes, showing you how you can take advantage of the new features to improve your applications' capabilities and performance.
    [Read This Article]  [Top]
    Feb 16, 2005 - Writing a Custom Membership Provider for the Login Control in ASP.NET 2.0
    In ASP.NET 2.0 and Visual Studio 2005, you can quickly program custom authentication pages with the provided Membership Login controls. In this article, Dina Fleet Berry examines the steps involved in using the Login control with a custom SQL Server membership database.
    [Read This Article]  [Top]
    Dec 29, 2004 - ClickOnce Deployment in .NET Framework 2.0
    In this article, Thiru Thangarathinam examines .NET 2.0's new ClickOnce deployment technology that is designed to ease deployment of Windows forms applications. This new technology not only provides an easy application installation mechanism, it also eases deployment of upgrades to existing applications.
    [Read This Article]  [Top]
    Dec 15, 2004 - A Sneak Peek at ASP.NET 2.0's Administrative Tools
    With ASP.NET 2.0, Microsoft has made great strides in increasing developer productivity and has made implementing previously complex solutions relatively easy. Where this version of ASP.NET really shines, however, is in its new administrative tools that allow developers to spend less time managing the configuration of the servers and software and more time developing great code.
    [Read This Article]  [Top]
    Nov 17, 2004 - The ASP.NET 2.0 TreeView Control
    Thiru Thangarathinam introduces ASP.NET 2.0's new TreeView control which provides a seamless way to consume and display information from hierarchical data sources. The article discusses this new control in depth and explains how to use this feature rich control in your ASP.NET applications.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry