Monday, March 31, 2008

And finally Wayne's Codesmith version for all procs prefaced with 'aspnet_':

<%@ CodeTemplate Language="C#" TargetLanguage="C#"  %>
<%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" %>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Assembly Name="System.Data" %>
<%@ Assembly Name="System.Design" %>
<%@ Import Namespace="SchemaExplorer" %>
<%@ Import Namespace="System.Data" %>
USE [<%=SourceDatabase.Name%>]

GO

<%

foreach(CommandSchema command in SourceDatabase.Commands)
{
 %>
 
 <%
 if ((command.Name.Length>7) && (command.Name.Substring(0,7) == "aspnet_"))
 {
%>
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[<%=command.Name%>]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[<%=command.Name%>]

GO

<%
 }
}
%>

ASP.NET | CodeSmith | Dina | T-SQL
Monday, March 31, 2008 7:09:06 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Sunday, March 30, 2008

After generating all CRUD procs with several different naming prefixes, my database was looking messy. So I knew what I wanted to produce but I needed to get rid of all these other procs. So how to quickly drop all the procs. Wayne said he had a codesmith template for it but I couldn't wait. I google'd and found another person that had the same problem after a heavy CodeSmith NetTiers session. His method was not too different from my post from yesterday. I did my final gen of procs via NetTiers but instead of going into the database, sent them to a file. I opened the file to find the following code which should have been both obvious in that NetTiers would need it and where I should look for it:

BEGIN

DECLARE @procedureName SYSNAME

DECLARE c CURSOR FOR

SELECT name FROM sysobjects WHERE type = 'P' AND objectproperty(id, 'IsMSShipped') = 0

AND name LIKE 'NetTiers_%' AND name NOT LIKE 'WW_{0}_%'

OPEN c

FETCH NEXT FROM c INTO @procedureName

WHILE @@FETCH_STATUS = 0

BEGIN

EXEC('DROP PROC ' + @procedureName)

FETCH NEXT FROM c INTO @procedureName

END

CLOSE c

DEALLOCATE c

END

 

Sunday, March 30, 2008 7:02:01 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, March 28, 2008

After using NetTiers for a couple of weeks now, here are some suggestions for usage:

1) Use NetTiers like any third party library. Build it and include the libraries. Do not alter code inside generated libraries unless mission critical. I also use the Microsoft.Patterns library. They ship the code but I don't alter it, I just use the built libraries. 

2) Prefix the library namespace with NetTiers so that the generated libraries look like NetTiers.Entities, NetTiers.Data, etc.

3) If you use NetTiers to generate your CRUD, set the ProcedurePrefix value to NetTiers_. When you are looking through a million procs, it easier to pass a whole section based on alphabetical sorting. If you use AspNet Membership, you will be accustomed to this naming schema as those procs are prefixed with aspnet_

4) If you create your own procs, prefix those procs to something that you won't confuse with any other library's procs, such as 'cust' for custom. Of cource, IncludeCustoms is set to true and CustomProcedureStartsWith should be set to 'cust_{0}_' so that a table name of Profile should have a custom proc of cust_Profile_SelectAll.

5) While still getting your template settings figured out:

  • Don't set ExecuteSQL to true until you have tested your generated SQL and looked through what was created.
  • Set LaunchVisualStudio to true and save yourself a few clicks.
  • Set ViewReport to false. You don't need another browser to open while you are still figuring out your templates.

6) Build the Web Service and the Admin site. Even if you don't plan to use AJAX or you have your own admin pages already built, these are just more examples of NetTiers code usage. Then when you need a data backdoor or quick AJAX, you are that much closer.

7) NetTiers documentation suggests using DeepLoad to get to a related table via FK. I can see how this would be used in their example of list of Orders in a grid and you also want to display the Customer's Name in the grid. What if you had a table of ProfileItems and a table of UserProfileItems and you wanted a list of all the ProfileItems in a grid with this user's settings? With the NetTiers usual get based on FK from either table, you won't get the grid I want (right?). So in that case, I'll create a custom proc with the proper bind.

Friday, March 28, 2008 8:03:23 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, March 27, 2008

I have a table with two FKs. NetTiers creates a stored proc for the PK as well as a stored proc for each FK however it doesn't create a stored proc that uses both FKs as the IN params. So I need to create this in a way that NetTiers can discover it and build the code objects to support it.

First I have to create the stored proc with a discoverable name. This requires several settings in the NetTiers template. First, that I want custom stored procs discovered so IncludeCustoms=true. Second, I want any stored procs to have a naming prefix so ProcedurePrefix=usp. Third, I need to handle the actual name of the stored proc. NetTiers uses discovery based on a template where the zeroth parm is the table name and the first parm is the Procedure Prefix so CustomProcedureStartsWith={1}_cust_{0}_. The remainder of the stored proc name is irrelevant but what is returned is very important. I usually return all columns which is NetTiers default object handling. If I choose not to include all columns, I would have to deal with an IDataReader or a DataSet.

If all the other stored procs and NetTiers code has been generated and you only new a few stored procs to be discovered, make sure to set ExecuteSQL=false and SourceTables=(only immediate tables.)

Once you generate your objects, you can verify the stored proc was discovered by looking in the Data layer in the base directory for the TableNameProviderBase.generatedCore.cs in the Custom Methods region.

Thursday, March 27, 2008 9:00:03 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |