|
YOUR FEEDBACK
|
TOP MICROSOFT .NET LINKS SQL Server 2005 Jerry Dixon's Exclusive New Column: SQL Server 2005 for the .NET Developer
Get the most out of your data with SQL 2005
By: Jerry Dixon
Nov. 27, 2005 03:15 PM
For most of this year, I've been giving presentations and teaching classes on various aspects of Visual Studio 2005 and SQL Server 2005. In my consulting role, I've been constantly presented with problems that, while definitely solvable with current tools, simply screamed for the new products. Alas, like most of you, I haven't been in a position to use these tools in a production environment. Now the wait is over. By the time you read this, production versions of both products should be available to the general public. Now all we need is to help each other learn how to make the best use of the new and improved features that these products provide. That's where .NET Developer's Journal comes in.
CLR Integration Design Considerations So how does one know when objects should be written in one way or the other? In general, .NET will be the better choice when there is complex logic involved, when built-in .NET Framework classes would be helpful, or when CPU-intensive tasks are performed. The native code produced by .NET excels in these situations. T-SQL, on the other hand, should be used when there are extensive data access or batch operations to be performed. Of course, specific situations may dictate a departure from these general rules. (Remember not to sell T-SQL short. As we will discuss in a future article, T-SQL has gained many new capabilities itself, and can definitely give .NET a run for its money.) Not all such decisions should be made based on performance alone, however. Application design and maintenance should also be considered. Because we can now write stored procedures in .NET, we could easily place all of our business logic in the database. Few would argue in favor of this, at least in the general case. However, this is another idea that has been proposed. The fact that our database is much more powerful than it used to be is no reason to abandon good, solid application design principles. CLR integration should be used as an additional tool with which to build a high-performance data layer, not to remove the need for a well-designed business-logic tier. .NET Object Creation It is quite likely that I will want to test and debug the project while I am working on it, so Visual Studio displays the question shown in Figure 4. It is asking me whether I want to enable debugging. Selecting "Yes" allows debugging, but will cause all managed threads that are currently running on the selected SQL Server to stop. This is necessary in order to begin the debugging process. If this is unacceptable, I can select "No" and forego the ability to debug. At this point, I have a standard-looking Visual Studio project. If I browse the project with Solution Explorer, I will see that a few assemblies have automatically been referenced. The two assemblies of most interest here are System.Data and sqlaccess. The sqlaccess assembly contains classes that allow .NET code to manipulate objects inside of SQL Server, such as tables. The System.Data assembly contains classes that we will code against inside our managed objects. One especially important namespace inside System.Data is System.Data.SqlServer. This namespace contains many classes that we will use on a regular basis. A few of these are summarized in Table 1. Why should we use these classes instead of the SqlConnection and SqlCommand classes found in System.Data.SqlClient? The answer is: performance and reliability. Remember that this code is different from code in a "normal" assembly in one major respect: it is invoked by SQL Server, and runs inside SQL Server. The SqlServer classes allow code to communicate directly with SQL Server via an internal, optimized data provider. The provider used by SqlClient classes is not as efficient in this case, as it is optimized for code that runs outside of SQL Server. To create my managed SQL object, I select "Add New Item..." from the Project Menu. The dialog box shown in Figure 5 appears. This is where I select the actual object type that I want to create. In this example, I want to create a new user-defined function, so I select that template from the dialog box. I then give the new function a name and click the "Add" button. The code shown in Listing 1 is automatically created. When working with managed SQL objects, there are two additional namespaces that we need to use. The first, System.Data.Sql, contains attribute definitions for each of the SQL object types. In this example, I am creating a user-defined function, so I need the SqlFunction attribute. If I want the name of the user-defined function to be the same as the .NET function name, I only need to include the SqlFunction attribute. However, I can change the name by passing a parameter to the SqlFunction constructor like this: [SqlFunction(Name:= "MyNewName")] The second namespace, System.Data.SqlTypes, provides access to the SQL Server-specific data types that I must use in my managed objects. I want to create a function that returns the factorial for a given number, so I change the code as shown in Listing 2. When built, this will create a C# function that I can call from SQL Server T-SQL statements. SQL Server Deployment Permission levels are very important. They control the rights that an assembly has with regard to resources outside of SQL Server. The most restrictive - and recommended - setting is SAFE. It allows no access to external resources. The next level, EXTERNAL_ACCESS, allows the use of the file system, the network, and the registry. The final level, UNSAFE, should be used with extreme caution. It allows access to any external resource to which the SQL service account has access. This can be very dangerous and should be allowed only for the most trusted assemblies. Whichever setting is selected, it is important to note that not all Framework classes can be used when creating SQL objects. Only those classes marked as safe for SQL Server can be used. Excluded classes include those that could cause SQL Server instability, such as those in the System.Threading namespace. See the Framework documentation for specifics. When the CREATE ASSEMBLY statement has been executed, the assembly will be imported into the system. The next step is to create a T-SQL wrapper for the user-defined function. Refer again to Listing 3. The wrapper is created by using the new EXTERNAL NAME clause. We start by creating a regular T-SQL function, but instead of writing the function implementation, the EXTERNAL NAME clause is used. This clause specifies the fully qualified name of the .NET function, starting with the assembly name given in the CREATE ASSEMBLY statement. Testing Summary YOUR FEEDBACK
MICROSOFT .NET LATEST STORIES
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING NEWS FROM THE WIRES
|
||||||||||||||||||||||||||||||||||||