Part IV: Building Effective Applications with ADO.NET

Questions That Should Be Asked More Frequently

  1. Q. Should I rely on data binding in an application that I plan to distribute?

  2. A. I rely on data binding when I build the user interface for an application. It lets me develop the basic user interface quickly with a small amount of code. Once I'm comfortable with the layout of the user interface and the schema of the data that the application uses, I consider whether to continue relying on data binding. If I need more control than I can achieve using data binding, or if I decide that relying on data binding will not save time in completing the application, I replace the data binding functionality with my own code.

    You'll notice that step 11 in the chapter's main sample application still relies on a bound DataGrid control to display the contents of an order. I disabled the DataGrid's updating features, but I felt that trying to replace the DataGrid's functionality would require a great deal of time without providing enough value to make that effort worthwhile.

  3. Q. Can I bind controls with an untyped DataSet?

  4. A. Absolutely. You can still bind controls at design time with untyped DataSet objects whose schemas you define at design time through the Property pages. You can also bind controls at run time with both typed and untyped DataSet objects using the code I showed you earlier in the chapter.

    Visual Basic .NET

    'Binding a TextBox to a DataColumn TextBox.DataBindings.Add("Text", DataSet, "TableName.ColumnName") 'Binding a DataGrid to a DataTable DataGrid.DataSource = DataSet DataGrid.DataMember = "TableName"

    Visual C# .NET

    //Binding a TextBox to a DataColumn TextBox.DataBindings.Add("Text", DataSet, "TableName.ColumnName"); //Binding a DataGrid to a DataTable DataGrid.DataSource = DataSet; DataGrid.DataMember = "TableName";

  5. Q. I have to load a lot of data when my application starts up. Any recommendations?

  6. A. Make sure you really need all that data. Obviously, if you can retrieve fewer rows and/or columns, it will take less time to fetch the results of your queries. Another option is to rely on the threading support in the .NET Framework to load data on another thread as the application starts up. For more information, see the documentation for the System.Threading namespace in the .NET Framework SDK. The .NET Framework simplifies threading, especially for Visual Basic users, but threading is still an advanced topic and beyond the scope of this book.

  7. Q. Why does the code in step 11 use a DataView rather than the DataTable to determine the position of the current order?

  8. A. If you mark a DataRow as deleted, it will still reside in the DataTable object's Rows collection. The application allows the user to mark an order as deleted. If the application were to rely solely on the DataTable object, it would require a great deal more code to skip orders that are marked as deleted while navigating through the remaining orders.

    Instead, the application uses the DataView object. With the default setting for the DataView object's RowStateFilter property, rows marked as deleted are not visible through the DataView, which simplifies the process of navigating through the remaining orders. The CurrencyManager object behaves in the same way.

  9. Q. How can I achieve pessimistic locking in a multi-tiered application that relies on a stateless middle tier?

  10. A. As I stated earlier in the chapter, only a small percentage of applications truly require pessimistic locking. Pessimistically locking data in a multi-tiered application with a stateless middle tier is definitely an advanced scenario. Airline reservation systems require this functionality. The user requests a seat on a flight, and the application locks that seat so that no one else can purchase it.

    Consider the architecture for a moment. Because the application accesses the database through a stateless middle tier, this means the application must allow the user to maintain locks on data without a live connection. Offhand, I don't know of any database that lets you persist a lock on data so that you can disconnect and later reconnect while the lock remains.

    However, you could devise your own locking scheme to achieve this functionality. To be honest, I haven't deployed large multi-user applications that rely on this type of architecture. But if my livelihood depended on developing such applications using SQL Server as the back end, here's what I'd do:

    1. Set the database's security so that users can modify the contents of the table only through calls to stored procedures.

    2. Add two columns to the table—one to contain a unique lock key and one to indicate the date and time the user successfully locked the row.

    3. Create a stored procedure that allows the user to request a lock on a row. The stored procedure will take the row's primary key and a GUID as input parameters. The stored procedure marks the row of data as locked if it is not already locked. Here's an example of such a stored procedure:

      CREATE PROCEDURE spPessimisticLockAcquireLock (@ID int, @LockID uniqueidentifier) AS UPDATE tblPessimisticLock     SET LockAcquired = GetDate(), LockID = @LockID     WHERE ID = @ID AND LockAcquired IS NULL

    4. Create a stored procedure that lets the user modify the contents of the row. The stored procedure takes parameters for the row's primary key columns, the new data for the column, and the lock key. The stored procedure updates the row only if the lock key supplied matches the one in the database. If the stored procedure successfully updates the row, it will mark the row as available.

      CREATE PROCEDURE spPessimisticLockUpdateRow (@ID int, @DescCol varchar(32), @LockID uniqueidentifier) AS UPDATE tblPessimisticLock     SET DescCol = @DescCol     WHERE ID = @ID AND LockID = @LockID IF @@ROWCOUNT = 1 BEGIN     SET NOCOUNT ON     UPDATE tblPessimisticLock         SET LockAcquired = NULL, LockID = NULL         WHERE ID = @ID AND LockID = @LockID END

    5. Create a stored procedure that the user can call to mark the row as available again.

      CREATE PROCEDURE spPessimisticLockReleaseLock (@ID int, @LockID uniqueidentifier) AS UPDATE tblPessimisticLock     SET LockAcquired = NULL, LockID = NULL     WHERE ID = @ID AND LockID = @LockID

    6. Create a job that will clean up all the locks that have not been released in a timely fashion. The following query locates rows marked as locked that have been locked for more than five minutes and marks those rows as available:

      UPDATE tblPessimisticLock     SET LockAcquired = NULL, LockID = NULL     WHERE DateAdd(mi, 5, LockAcquired) <= GetDate()



Microsoft ADO. NET Core Reference
Microsoft ADO.NET (Core Reference) (PRO-Developer)
ISBN: 0735614237
EAN: 2147483647
Year: 2002
Pages: 104
Authors: David Sceppa

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net