#Sql Basics -Triggers

Triggers :

A trigger is a special kind of stored procedures that automatically executes when an event occurs in database.You cannot invoke triggers explicitly.

Types of triggers :

1.Instead of Trigger

2.After Trigger(for Triggers)–Does not supports view.

Instead of Triggers :

As the name suggest,you take control over Insert/Update/Delete and you decide if you really want to Delete a table record that has to be deleted even though you give a delete statement over table.


create trigger trigeer_name on your_table 

instead of delete 

As

declare @id int;
Begin
select id=d.Id from deleted d;

/**your operation**/

End

After Trigger :

Events that has to occur after Insert/Update/Delete are termed as After Triggers.


Create trigger your_triggername on your_table;

for Insert;

as

begin

select id=d.Id from inserted (inserted is a special table provided by sql)

/**your operation **/

end

How to get column values after/before  statement(Insert/Update/Delete) gets executed in triggers ?

Sql provides special tables for triggers namely inserted,deleted which will hold the records/column values,we can make use of this table in after/instead of triggers.

 

#Common Performance Traps in Entity Framework

I recently read an article from SimpleTalk. It pretty much covered the common mistake and i am listing the one which i commonly do.

Bring only Columns you require,instead of All :

Lets assume we need only first name and last name from the table User  which holds information of user details (First Name, Last Name, Telephone No,Email Id,Location).

we need to write a query to bring all users whose location is  NewYork.

Most Common Query we write:


string Location= "NewYork"

var result= dbcontext.User.where(x=>x.Location==Location).ToList();

foreach(var usersinnewyork in result)

{

Console.WriteLine(usersinnewyork.FirstName);

Console.WriteLine(usersinnewyork.LastName);

}

In the above query the result brings all the columns while we need only first and last name.We might not be aware of impact of query we write,but identifying such queries in application would help us to avoid certain performance issues.

Modified Query with Anonymous Object :


string Location= "NewYork"

var result= dbcontext.User.where(x=>x.Location ==Location).Select( x=>new 

{
FirstName =x.FirstName,
LastName =x.LastName
});

In the above query we only bring what we need (first and last name).

 

#Basics of Views-Sql Server

Views : They are virtual table and are generally combination of 2 or 3 tables.Being said Virtual they do not occupy space like a normal table.

Indexes on View :

Views are virtual table by default,to use index it’s mandatory to have a physical column.To enable indexes its mandatory to use SCHEMABINDING with views.


create view yourviewname 

with schemabinding 

as

select  v1.column1 ,v1.column2 from v1 

Refreshing Views:

Since views are virtual tables,there might be cases where we need to refresh a view when underlying table used in view changes.

Execute SP_RefreshView "yourviewname"

 

Insert/Update/Delete with Views:

 Single select must be used in view with check option enabled.

#Sql Basics -Union vs Union All

Union – Merges the Content of two or more tables without duplicates.

Union All-Merges the Content of two or more tables which include duplicates.

For union/union all between two or more tables you must have same column name including the data type.

Performance : 

Union All does not requires elimination of duplicate records and the performance is high when compared with Union since it requires an additional operation to remove the duplicate values.

# Dealing with Constructor-Over InJection-Part 1

What is constructor-over Injection ?

while constructor-injection is the most common way to resolve the dependency,there are cases where design of improper system such as violating the SOLID  would lead to have many dependency getting loaded in the constructor.

Example :


public class SampleClass

{

public SampleClass(IDependency1 Dependency1 ,IDependency2 Dependency2 ,,IDependency3 Dependency3 ,IDependency4 Dependency4 ,,IDependency5 Dependency5 ,IDependency6 Dependency6 )

{

//Constructor Over injected as you need 6 Dependency to be resolved when you create instance of SampleClass.

}

}

In the above example to create the instance of SampleClass,it requires 6 Dependency to get resolved.

The above code clearly indicates the following

1.we have violated the SOLID principles,mainly the single responsibility principle,the sample class listed is clearly doing more than one thing.

2.Improper Design of classes.

How to deal with Constructor Over Injection :

Facade Services : You apply the Facade pattern and decompose the constructor arguments as many  as possible.

 

 

#Thread Safety Over Static -Tips

1.Are Static class with Static Method Thread Safe ?

Yes,when the static fields/members are of value type.

No when the static fields/members  are of reference type.

2.Are Static Fields inside a non-static method Thread Safe ?

Yes,when the static fields/members are of value type.

No when the static fields/members  are of reference type.

 

 

 

#Areas in MVC

It is hard for maintaining the controllers and views as project grows,

Areas in MVC provides solution by letting you to have controller,model,view per module.

For instance if you have  four modules,you could have four areas with its own controller,model and view.

Capture.PNG
Areas in MVC

In the example above,There are two modules  ExecutiveSponsors and Users put into an area.

Accessing and Configuring the area:

1.You can define the routes for the controller in the Corresponding AreaRegistration.

2.To access the controller from the browser,you must append the area name before the controller.

i.e http: //yourdomainname /Areaname/Controller

Example :

http://localhost:/ExecutiveSponsor/Sample.

 

#oops Basic

  1. You cannot extend or inherit more than 1 abstract class (C# does not provides multiple inheritance.)
  2. Struct cannot implement an abstract class.
  3. Struct can implement interfaces.

class MyClass : a,b ---ERROR--Cannot implement multiple base class.
{

}

abstract class a
{

}

abstract class b
{

}

Cascading Delete in Entity Framework with Fluent API

What is Cascading Delete ?

There may be situation where if a record in parent table is deleted than corresponding records in child tables(Foreign Key ) are also deleted.

Parent and Child Mapping with Fluent Api in Entity Framework:

I am not going to describe how to map parent and child table with fluent api. you can read it more about here.

In the below table diagram, the AssessmentChatRoom is the base parent whose foreign key is referenced by ChatRoomData and ChatRoomParticipants table.

Capture

Mapping the relation with FluentAPI and Setting the Cascade Delete:

AssessmentChatRoom is the parent and ChatRoomData and ChatRoomParticipants are the child tables.In the ChatRoomData WillCascadeDelete() Property is set to true.

 

Parent Table:


public class AssesmentChatRoomConfig
 {
  public AssesmentChatRoomConfig()
{
ToTable("AssessmentChatRooms").HasKey(e => e.Id);
Property(e => e.Id).HasColumnName("Id");
Property(e => e.Name).HasColumnName("Name");
Property(e => e.LastUpdatedOn).HasColumnName("LastUpdatedOn");
Property(e => e.CreatedOn).HasColumnName("CreatedOn");
Property(e => e.AssessmentChatRoomParentId).HasColumnName("AssessmentChatRoomParentId");
}
 }

ChildTable


public class ChatRoomDataConfig 
 {
public ChatRoomDataConfig()
{
ToTable("ChatRoomData").HasKey(e => e.Id);
Property(e => e.Id).HasColumnName("Id");
Property(e => e.AssessmentChatRoomId).HasColumnName("AssessmentChatRoomId");
Property(e => e.ChatText).HasColumnName("ChatText");
Property(e => e.PostedBy).HasColumnName("PostedBy");
Property(e => e.TimeStamp).HasColumnName("TimeStamp");
Property(e => e.MessageType).HasColumnName("MessageType");
HasRequired(s => s.AssessmentChatRoom)
.WithMany(s => s.ChatRoomDatas).HasForeignKey(s => s.AssessmentChatRoomId).
WillCascadeOnDelete(true); // set Cascade delete
}
}

Deleting the Parent Table with Cascade Delete :

1.Get the parent record id and its related child record.


var result =dbcontext.Assessmentchatroom.where(x=>x.id == id);

 

 

The above query will bring only the parent record and you might see the child records to be null,this is because the entity framework by default has lazy loading enabled. It is not a good idea to disable lazy loading,instead use include keyword and retrieve the child elements.

Retrieving Child Record using Include Keyword of entity framework:

Its possible to let know the parent to load the child elements using include keyword as below.

var entity = Context.AssessmentChatRooms.
Include(c=>c.ChatRoomDatas.Select(b=>b.AssessmentChatRoom)).
where(x=>x.id =id)

Code to Remove :

This is a pretty standard way to remove.you just got to pass the parent entity and got to call the Remove method of entity framework and this will in turn delete all the child elements,since cascade delete is set to true.

 

 

MVC Validation- Custom Server and Client Side

Server Side Validation :

MVC Provides custom validation  via ValidationAttribute and IValidatableObject.

Server Side Validation with ValidationAttribute :

To implement custom server side validation,we must inherit from ValidationAttribute. In the below sample,i have a custom validator that checks if date is greater than todays date.


public class ValidateDate : ValidationAttribute
{
public ValidateDate()
{
ErrorMessage = "Date Time Cannot be greater than today's date";
}
public override bool IsValid(object value)
{
var datetime = Convert.ToDateTime(value);
if (datetime > DateTime.Now)
{
return false;
}
return true;
}

}

Usage : To use the above attribute,its enough to annotate over the property.


public class SampleModel
{
[Required]
[ValidateDate] //-----Custom Validator------//
public DateTime StartdateTime { get; set; }
}

As you can see above the validation works only after post back(after submit button) and the validation happens in server side.

Handling Custom Validation from Client Side :

Apart from javascript validation over model,mvc also provides custom validation from client side.

Implementing custom client side validation :

IClientValidatable interface indicates the mvc framework that the cutom validator supports client side validation. It provides a contract named  IEnumerable<ModelClientValidationRule> GetClientValidationRules that is responsible for returning validation rules in client side.

In the code below is the custom client side validator that implements IClientValidatable interface which displays an error message when date is greater than today’s date.


[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
 public class ValidateDate : ValidationAttribute,IClientValidatable
 {
 public ValidateDate()
 {
 ErrorMessage = "Date Time Cannot be greater than today's date";
 }
 public override bool IsValid(object value)
 {
 var datetime = Convert.ToDateTime(value);
 if (datetime &gt; DateTime.Now)
 {
 return false;
 }
 return true;
 }

public IEnumerable&lt;ModelClientValidationRule&gt; GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
 {
 var modelvalidtorrule = new ModelClientValidationRule();
 modelvalidtorrule.ValidationType = "dategreaterthan"; //---will be used in registering with jquery adaptor---//
 modelvalidtorrule.ErrorMessage = ErrorMessage;
 return new[] {modelvalidtorrule};
 }
 }

Registering the Custom Validator with Jquery Adaptor :

Inorder to achieve the client side validation,we must add and register to jquery validator and adapters. 

Adding custom validator to Jquery Validator :


jQuery.validator.addMethod('dategreaterthan', function (value, element, params) {
 var currentDate = new Date();
 if (Date.parse(value) &gt; currentDate) {
 return false;
 }
 return true;
 }, '');

Adding custom Validator to Jquery Adaptor :


jQuery.validator.unobtrusive.adapters.add('dategreaterthan', function (options) {
options.rules['dategreaterthan'] = {};
options.messages['dategreaterthan'] = options.message;
});

Capture