Introducing SQL+ .NET

Every once in a while, something comes along that is just, well, better. SQL+ .NET is one of those things that once you start using, you’ll wonder how you ever got along without it.

So what is SQL+ .NET? It is actually two components that work together.
  1. A set of semantic tags that you add to your SQL routines in the form of comments.
  2. A Visual Studio plugin that reads your tagged procedures and generates an object-oriented class library that is ready for production.
The simplest way to understand why it is fast becoming the go-to product of choice for SQL developers is to actually see what it does.

Given the following stored procedure,
  1. CREATE PROCEDURE [dbo].[FeedBackInsert]  
  2. (  
  3.     @Name varchar(32),  
  4.     @Subject varchar(32),  
  5.     @Email varchar(64),  
  6.     @Message varchar(1024),  
  7.     @FeedBackId int out  
  8. )  
  9. AS  
  10. BEGIN  
  11.     SET NOCOUNT ON;  
  12. INSERT INTO dbo.FeedBack  
  13. (  
  14.     [Name],  
  15.     [Subject],  
  16.     [Email],  
  17.     [Message],  
  18.     [CreatedDate]  
  19. )  
  20. VALUES  
  21. (  
  22.     @Name,  
  23.     @Subject,  
  24.     @Email,  
  25.     @Message,  
  26.     GETDATE()  
  27. )   
  28. SET @FeedbackId = SCOPE_IDENTITY();   
  29.          RETURN 1;  
  30. END;  
All we need to do is to generate our ADO.NET code. So, simply add the following tag to the routine definition.
  1. --+SqlPlusRoutine  
  2.     --&SelectType=NonQuery  
  3.     --&Comment=Inserts a new record into the feedback table  
  4.     --&Author=Alan Hyneman  
  5. --+SqlPlusRoutine  
  6. CREATE PROCEDURE [dbo].[FeedBackInsert]  
And, that’s it. You can now go to your Visual Studio project, right-click the project, and choose the SQL Plus Build menu option.
 
 
SQL+ .NET does the rest for you. The generated code contains an input object which has all our input parameters as well as methods for validation.
  1. /// <summary>  
  2. /// Input object for FeedBackInsert method.  
  3. /// </summary>  
  4. public class FeedBackInsertInput  
  5. {  
  6.     public string Name { setget; }  
  7.     public string Subject { setget; }  
  8.     public string Email { setget; }  
  9.     public string Message { setget; }  
  10.    
  11.     /// <summary>  
  12.     /// Use this method to validate the instance.  
  13.     /// If the method returns false, the ValidationResults list will be populated.  
  14.     /// </summary>  
  15.     public bool IsValid()  
  16.     {  
  17.         ValidationResults = new List<ValidationResult>();  
  18.         return Validator.TryValidateObject  
  19.                  (thisnew ValidationContext(this), ValidationResults, true);  
  20.     }  
  21.    
  22.     /// <summary>  
  23.     /// ValidationResults populated from the IsValid() call.  
  24.     /// </summary>  
  25.     public List<ValidationResult> ValidationResults{ setget; }  
  26. }  
An output object that contains all the output parameters, return value, and any result sets that would be returned as a result of executing our stored procedure,
  1. /// <summary>  
  2. /// Output object for FeedBackInsert method.  
  3. /// </summary>  
  4. public class FeedBackInsertOutput  
  5. {  
  6.     public int? FeedBackId { setget; }  
  7.     public int? ReturnValue { setget; }  
  8.   
  9.     /// <summary>  
  10.     /// This is the collection of TransientErrors that occured during the execution of the call.  
  11.     /// </summary>  
  12.     public List<SqlException> TransientErrors { setget; }  
  13. }  
And, a service method that takes the input object and returns the output object.
  1. /// <summary>  
  2. /// Inserts a new record into the feedback table  
  3. /// SQL+ Routine: dbo.FeedBackInsert - Authored by Alan Hyneman  
  4. /// </summary>  
  5. public FeedBackInsertOutput FeedBackInsert(FeedBackInsertInput input)  
  6. {  
  7.     //additional code - removed for simplification of article  
  8. }  
And, to call our procedure using our newly generated code is as simple as this.
  1. //create the input object  
  2. FeedBackInsertInput input = new FeedBackInsertInput()  
  3. {  
  4.     Email = "[email protected]",  
  5.     Name = "The Ninja Coder",  
  6.     Subject = "Is SQL+ dot net for real",  
  7.     Message = "Yes, very much so and it is the tool that SQL developers have been waiting for.",  
  8. };  
  9.    
  10. //create the service   
  11. Service service = new Service("your connection string");  
  12.    
  13. //call the service and get the result  
  14. FeedBackInsertOutput output = service.FeedBackInsert(input);  
Now, if that was all SQL+ .NET did, it would be a very useful tool, however, it does a whole lot more. SQL+ .NET gives you the ability to add validation tags to your parameters, and that information is then escalated into the generated code. For instance, if we want to make it so that all our parameters are required, we simply add the required tag like so.
  1. CREATE PROCEDURE [dbo].[FeedBackInsert]  
  2. (  
  3. --+Required  
  4.     @Name varchar(32),  
  5.    
  6. --+Required  
  7.     @Subject varchar(32),  
  8.    
  9. --+Required  
  10.     @Email varchar(64),  
  11.    
  12. --+Required  
  13.     @Message varchar(1024),  
  14.    
  15.     @FeedBackId int out  
And now, our input object can enforce that validation through the use of data annotations, and the IsValid() method would then test your properties to enforce the validation, all by adding a few tags to your stored procedure.
  1. /// <summary>  
  2. /// Input object for FeedBackInsert method.  
  3. /// </summary>  
  4. public class FeedBackInsertInput  
  5. {  
  6.     [Required(AllowEmptyStrings = false)]  
  7.     public string Name { setget; }  
  8.    
  9.     [Required(AllowEmptyStrings = false)]  
  10.     public string Subject { setget; }  
  11.    
  12.     [Required(AllowEmptyStrings = false)]  
  13.     public string Email { setget; }  
  14.    
  15.     [Required(AllowEmptyStrings = false)]  
  16.     public string Message { setget; }  
  17.     /// <summary>  
  18.     /// Use this method to validate the instance.  
  19.     /// If the method returns false, the ValidationResults list will be populated.  
  20.     /// </summary>  
  21.     public bool IsValid()  
  22.     {  
  23.         ValidationResults = new List<ValidationResult>();  
  24.         return Validator.TryValidateObject  
  25.         (thisnew ValidationContext(this), ValidationResults, true);  
  26.     }  
  27.    
  28.     /// <summary>  
  29.     /// ValidationResults populated from the IsValid() call.  
  30.     /// </summary>  
  31.     public List<ValidationResult> ValidationResults{ setget; }  
  32. }   
There are validation tags for required, string length, ranges of values, formatting options like email, phone, and credit cards. There are tools to build enumerations from tables, and associate those enumerations with parameters. You can enumerate return values for procedures that may have different logical outcomes and you can even use these tags, in tandem with resource files, to create a class library that supports multiple languages.

Alan Hyneman has been working with computers and developing software for nearly 40 years and has just taken over as the CTO for Comfort Depot.


Similar Articles