Apr 29

Powerful Codesmith data layers templates

Posted By Ahmed El-Kilani On 29 Apr 2008 No Comments »

Codesmith tools is one of the powerful template-based code generation tool. For more info go to www.codesmithtools.com

Codesmith has various predefined templates for genrating domain model, N-tires, CSLA and NHibernate classes or mapping files.
In fact none of predefined templates are suitable for easy and quick use. NetTiers is the best but it needs a lot of customization and also generates a lot of code which is not necessary in most cases.
Today I come with a Generator template to generate domain model classes and data access layer and also CRUD stored procedures.

The final output of the template (generated for Northwind Category table) is figured below:

SqlDB class is the class containing Execute, ExecuteScalar, ExecuteReader, FillTable methods, which are responsible for creating database connection and execute queries and stored procedure on the database.

AbstractDataProvider is the base class for each Entity DataProvider class, it abstracts the definitions for the common base methods such as select, insert, update and delete.

AbstractEntity Class is the base class for each Entity class. IComparable interface is implemented to allow dynamic sorting for domain objects into lists; for more info about default comparer see :
http://blogs.a-h-m-e-d.com/Blogs/post/Another-dynamic-comparer-for-sorting-lists-(-very-simple-).aspx

Features:
- DeleteByFlag:

This feature allows you to specify a boolean column in a given table to be a flag for deleted rows instead of deleting them permenantly from database.
Select stored procedures select only rows of a table which has the DeleteFlagColumn set to 0 (False). Delete stored procedure just updates the colum to 1 (True) instead of the delete action.

-UseCollection:
Returned rows can be returned as generic lists if UseCollections option is set to True else a DataTable is returned.

-Generator template:
This template will generate all classes and stored procedures needed for interaction with database for given table(s).

Generator.rar (13.38 KB)

Feb 10

Microsoft SQL Server 2008 has started out new technologies which aid to imporve performance, security, scalability, developer productivity and more..
New features and enhansments include environment enhancment, services, ADO .Net and Linq integration, and also T-SQL improvements.

Most significant new features:

  • T-SQL Intellisence
  • Filestreaming support (more..)
  • Data Encryption
  • Plan Freezing
  • Compression features (more..)
  • Backup Compression.
  • Performance improvment and enhancements.
  • ADO .Net object services.
  • Synchronous net-changes change tracking.
    See more at microsoft's ...

T-SQL enhancements:

  • += operator.
  • Insert multiple records (insert t values (@x), (@y))
  • MERGE statement (Merges data between two tables)
  • UPSERT statement (Used to update records if exist or insert if new)

and other wonderful features..

New data types:

  • DATE (Stores only date value)
  • TIME (Stores only time value)
  • DATETIME2 (Increased second and years range of the existing datetime)
  • DATETIMEOFFSET (Indicating the time zone that time blogs to)
  • FILESTREAM
  • HIERARCHYID (For working with hierarchical data)

Jan 08

Database backup and restore are the most important actions we need for our published web applications. Some shared hosts like Godaddy do not allow backup/restore for your databases, although godaddy has introduced backup/restore actions but is only for backup files (*.bak) have been created by their system, however *.bak files that made from local machines or any other system cannot be restored.
Here is how to backup/restore databases programatically without the need to execute backup or restore commands.

Backup:
You can backup all or choosen tables into an xml file. The following command gets all table: 

SELECT TABLE_NAME
FROM   INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE 'BASE TABLE' AND
TABLE_NAME <> 'dtproperties'

By selecting all from the retrieved tables into one dataset and then calling DataSet.WriteXml() , would write all tables data into one xml file.

foreach (string table in tables)
{
    cmd.CommandText 
= string.Format("SELECT * FROM [{0}]",table);
    
DataTable dt = new DataTable(table);
    
da.Fill(dt);
    
ds.Tables.Add(dt);              
}


Restore:
1-
First step is to disable all constraints and delete all data in each table before insert statement can execute:

string beforeInsertComm = string.Empty;
beforeInsertComm "sp_msforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\" ";
beforeInsertComm +"DELETE [{0}]";
beforeInsertComm = string.Format(beforeInsertComm, table);
cmdBeforeInsert.CommandText beforeInsertComm;
cmdBeforeInsert.Connection.Open();
cmdBeforeInsert.ExecuteNonQuery();
cmdBeforeInsert.Connection.Close();
sb.Append(beforeInsertComm);

ALTER TABLE statement will disable constraint for all database tables, and will automatically be restored to its default value when closing the connection; therefore ALTER statement must be followed by DELETE statement in the same command execution so that DELETE execution will not be violated with foreign key constraints.

2- Restoring data read from xml by DataSet.ReadXml() to the database:
a- We must set indentity_insert to on to allow insert into identity columns:

string beforeInsertComm "IF(EXISTS(SELECT Name FROM SYSCOLUMNS WHERE COLUMNPROPERTY(OBJECT_ID('{0}'),Name,'ISIDENTITY') = 1))BEGIN ";
beforeInsertComm +"SET IDENTITY_INSERT [{0}] ON END ";
beforeInsertComm = string.Format(beforeInsertComm, dt.TableName);

b- Now comes the generating insert command for the given table:

sb.Append("INSERT INTO [" + dt.TableName + "](");
for 
(int 0x < dt.Columns.Countx++)
{
    
string column dt.Columns[x].ColumnName;
    
sb.Append("[" + column + "]");
    if 
(x < dt.Columns.Count - 1)
        sb.Append(
",");
}
sb.Append(
") VALUES (");
for 
(int 0y < dt.Columns.County++)
{
    
string column dt.Columns[y].ColumnName;
    
sb.Append("@" + column);
    if 
(y < dt.Columns.Count - 1)
        sb.Append(
",");

    
SqlParameter p = new SqlParameter();
    
p.ParameterName "@" + column;
    
p.SourceColumn column;
    
cmdInsert.Parameters.Add(p);
}
sb.Append(
")");


3- Reenable constraints:

sp_msforeachtable "ALTER TABLE ? CHECK CONSTRAINT all" 


Note:
For better performance ,Bulk insert command is one of the fastest solutions but can only run under sysadmin or bulkadmin roles.

Source code is available within attachments.
Hope that helps,
Enjoy

BackupRestore.rar (182.7 KB)
Jan 02

MS SQL 2000 and ON DELETE SET NULL

Posted By Ahmed El-Kilani On 02 Jan 2008 No Comments »

MS SQL Server 2000 lacks 'ON DELETE SET' statement which is supported by MySql, Oracle and recently MSSql Server 2005. When deleting a row or more in the database which are referenced by other rows, you will face a constraint violation, We can only cascade this action by setting ON DELETE CASCADE which forces all child rows to be deleted; but we may override this violation by defining the action to be taken when delete statement is executed,  ON DELETE SET NULL (which is not supported in MSSql 2000) will set null to the foreign key colum in child tables; here is a trigger to do the same action in MSSQL 2000:
Considering the following script:

create table Father (
FID 
int primary key,
FName 
varchar(20)
)
GO

Create table 
Child (
CID 
int primary key identity(1,1),
CName 
varchar(20),
FID 
int references Father(FID)
)
GO

alter table 
child add constraint FK_Child_FID
foreign key (fid) references father(fid)
on delete no action

GO

An Instead of delete trigger will be added to the Father table to perform the preceding action:

-- This trigger fix the shortage of MSSQL 2000 of lacking "ON DELETE SET NULL"
create trigger DeleteFather on Father
instead 
of delete 
As
begin

declare 
@fid int
select 
@fid=FID from deleted

update child set
FID = null 
where 
FID @fid

delete father where FID @fid
end
GO