Monday, May 27, 2013

Aps.net Cache Concepts

Cache is the technique of persisting the data in the memory for immediate access to requesting program calls. One of the most important factors in building high-performance, scalable Web applications is the ability to store items, whether data objects, pages, or parts of a page, in memory the initial time they are requested.

Although both Application and Cache objects look the same, the key difference between them is the added features provided by the Cache object like the expiration policies and dependencies. It means that the data stored in the cache object can be expired/removed based on some predefined time limit set by the application code or when the dependent entity gets changed whereas this feature is not available in the Application object.
Caches are two different types:

·         Page Level Output Caching
·         Fragment Caching              

Page Level Output Caching:
This is at the page level and one of the easiest means for caching pages. This requires one to specify Duration of cache and Attribute of caching.

Syntax: 
<%@ OutputCache Duration="60" VaryByParam="none" %>

The above syntax specifies that the page be cached for duration of 60 seconds and the value "none" for VaryByParam* attribute makes sure that there is a single cached page available for this duration specified.

* VaryByParam can take various "key" parameter names in query string. Also there are other attributes like VaryByHeader, VaryByCustom etc.

Fragment Caching:
Even though this definition refers to caching portion/s of page, it is actually caching a user control that can be used in a base web form page. In theory, if you have used include files in the traditional ASP model then this caching model is like caching these include files separately. In ASP.NET more often this is done through User Controls. Initially even though one feels a bit misleading, this is a significant technique that can be used especially when implementing "n" instances of the controls in various *.aspx pages. We can use the same syntax that we declared for the page level caching as shown above, but the power of fragment caching comes from the attribute "VaryByControl". Using this attribute one can cache a user control based on the properties exposed.

Syntax: 
<%@ OutputCache Duration="60" VaryByControl="DepartmentId" %>

The above syntax when declared within an *.ascx file ensures that the control is cached for 60 seconds and the number of representations of cached control is dependant on the property "DepartmentId" declared in the control. 

Add the following into an *.ascx file. Please note the use of tag "Control" and the cache declaration.

<%@ Control Language="C#"%>
<%@ outputcache duration="60" varybycontrol="DepartMentId" %>

<script runat="server">
private
 int _Departmentid=0;
public int DepartMentId
{
get{return _Departmentid;}
set{_Departmentid =value;}
}
//Load event of control
void Page_Load(Object sender, EventArgs e)
{
lblText.Text = "Time is " + DateTime.Now.ToString() + " for Department id = " 
+ _Departmentid + "\n";
}
</script>
<
asp:Label id="lblText" runat="server"></asp:Label>

Add the following to an *.aspx file. Please note the way "Register" tag is used; the declaration of control using syntax <[TagPrefix]:[TagName]>; Usage of property " DepartMentId". Open the page in two browsers and closely watch the Base form timing and the User control timing. Also note that the following page results in two copies or representation of user control in the cache.
Let us discuss about different expiration polices and dependencies that are supported.

Dependency:
Dependency means that the ad item can be removed from cache when the dependent gets changed So a dependent relationship can be defined on an item whose removal from the cache will depend on the dependent. There are three types of dependencies supported in ASP.NET.

·             File dependency: - Allows you to invalidate a specific cache item when a disk
based file or files change.
 Time-based expiration: - Allows you to invalidate a specific cache item depending
on predefined time.
Key dependency:- Allows you to invalidate a specific cache item depending when
another cached item changes.

File dependency:
public void displayAnnouncement()
        {
            string announcement = string.Empty;
            if( Cache["announcement"]==null )
            {
                StreamReader file = new StreamReader(@"D:\sekhar.txt");
                announcement = file.ReadToEnd();
                file.Close();
                CacheDependency depends = new CacheDependency(@"D:\sekhar.txt");
                Cache.Insert("announcement", announcement, depends);
                Response.Write(Convert.ToString(Cache["announcement"]));
            }
        }
        protected void Page_Init(object sender, EventArgs e)
        {
            displayAnnouncement();
        }

Above given method displayAnnouncement() displays banner text from Announcement.txt file
which is lying in application path of the file . Above method, first checks whether the
Cache object is nothing, if the cache object is nothing then it moves further to load the cache data
from the file. Whenever the file data changes the cache object is removed and set to nothing.

Time-based expiration:
Time based expiration provides an option to expire an item in the cache at a predefined time. The expiration time can be set as absolute time like 31st October 2005 12:00 or sliding time i.e. relative to the current time when the item is accessed.

    //Absolute Expiration
            Cache.Insert("StudentName", "Anish", null, DateTime.Now.AddDays(1), Cache.NoSlidingExpiration);
            ////Sliding Expiration
            Cache.Insert("StudentName", "Akarsh", null, DateTime.Now.AddDays(1),TimeSpan.FromSeconds(60));

Key dependency: Key dependency is similar to file dependency but the only difference is that instead of a file the item is dependent on another item in the cache and gets invalidated when the dependent item gets changed or removed. This option is useful when multiple related items are added to the cache and those items are to be removed if the primary item is changed. For e.g. employee number, name, address and salary are added to the cache and if the employee number is updated/removed all the related employee information are removed. In this case the employee number dependency can be used for other employee information.

string[] relatedKeys = new string[1];
            relatedKeys[0] = "EMP_NUM";
            CacheDependency keyDependency = new CacheDependency(null, relatedKeys);
            Cache["EMP_NUM"] = 5435;
            Cache.Insert("EMP_NAME", "Anish", keyDependency);
            Cache.Insert("EMP_ADDR", "Tampa", keyDependency);
            Cache.Insert("EMP_SAL", "33647", keyDependency);


Sunday, May 26, 2013

Object Initializers in c#.net


Object Initializers with Autoimpeleted Properties
Object initializers let you assign values to any accessible fields or properties of an object at creation time without having to explicitly invoke a constructor. The following example shows how to use an object initializer with a named type, Student. Note the use of auto-implemented properties in the Student class.
class Student
{
    ///these are auto-implemented properties
    public string Name { get; set; }
    public int Standard { get; set; }
    public int  Age { get; set; }

}

Student objstudent = new Student {Name = “Bharathi”, Standard =3, Age=7};

var studentInfos =
    from s in students
    select new { s. Name, s.Standard ,s.Age};
 
 
 
When this query is executed, the studentInfos  variable will contain a sequence of objects that can be accessed in a foreach statement as shown in this example:
 
foreach(var s in studentInfos)
{
   Console.writeline(“Student Name “+s.Name);
   Console.writeline(“Student Age “+p.Age);
 
}
 
 
select new {S.Name, StudentAge = S.Age};
 
Collection Initializers :
 
Collection initializers let you specify one or more element initializers when you initialize a collection class that implements IEnumerable. The element initializers can be a simple value, an expression or an object initializer. By using a collection initializer you do not have to specify multiple calls to the Add method of the class in your source code; the compiler adds the calls.
 
// The following code consolidates examples from the topic. 
class ObjInitializers
{
    class Student
    {
        // Auto-implemented properties. 
        public int Age { get; set; }
        public string Name { get; set; }
    }
 
    static void Main()
    {
        Student student = new Student {Age = 10, Name = "Akarsh" };
 
        List< Student > students = new List< Student >
        {
            new Student (){ Name = "Anish", Age=8 },
            new Student (){ Name = "Akarsh", Age=2 },
            new Student (){ Name = "Raja", Age=14 }
        };
 
 
 
        List< Student > moreStudents = new List< Student >
        {
            new Student (){ Name = "Akarsh", Age=5 },
            new Student (){ Name = "Anish", Age=4 },
            null
        };
 
        // Display results.
        System.Console.WriteLine(Student.Name);
 
        foreach (stud s in Student)
            System.Console.WriteLine(s.Name);
 
        foreach (stud s in Students)
            if (s != null)
                System.Console.WriteLine(s.Name);
            else
                System.Console.WriteLine("List element has null value.");
    }
}


Although object initializers can be used in any context, they are especially useful in LINQ query expressions. Query expressions make frequent use of anonymous types, which can only be initialized by using an object initializer, as shown in the following declaration.
var objStudent = new { Name = “Bharathi”, Standard =3, Age=7 };
Anonymous types enable the select clause in a LINQ query expression to transform objects of the original sequence into objects whose value and shape may differ from the original. This is useful if you want to store only a part of the information from each object in a sequence. In the following example, assume that a students object (s) contains many fields and methods, and that you are only interested in creating a sequence of objects that contain the student name and the Age.

Each object in the new anonymous type has two public properties which receive the same names as the properties or fields in the original object. You can also rename a field when you are creating an anonymous type; the following example renames the StudentAge field to StudentAge.

List View Template Control using Asp.net 3.5

Identifies the content for the group layout. It contains a placeholder object, such as a table cell (td), div, or span that will be replaced with the content defined in the other templates, such as the ItemTemplate and EmptyItemTemplate templates.
Identifies the content to render between groups of items.
Identifies the content to render for an empty item when a GroupTemplate template is used. For example, if the GroupItemCount property is set to 5, and the total number of items returned from the data source is 8, the last row of data displayed by the ListView control will contain three items as specified by the ItemTemplate template, and two items as specified by the EmptyItemTemplate template.
Identifies the content to render if the data source returns no data.
Identifies the content to render for the selected data item to differentiate the selected item from the other displayed items.
Identifies the content to render for alternating items to make it easier to distinguish between consecutive items.
Identifies the content to render when an item is being edited. The EditItemTemplate template is rendered in place of the ItemTemplate template for the data item being edited.
Identifies the content to render when an item is being inserted. The InsertItemTemplate template is rendered in place of an ItemTemplate template at either the start of the items displayed by the ListView control, or at the end. You can specify where the InsertItemTemplate template is rendered by using the InsertItemPosition property of the ListView control.
   
 
 
 string _connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            BindPersonDetails("Name ASC");
        }
    }

    ///
    /// Fires when Edit link is clicked
    ///

    ///
    ///
    protected void EditListViewItem(object sender, ListViewEditEventArgs e)
    {
        ListView1.EditIndex = e.NewEditIndex;
        // Rebind the details
        BindPersonDetails("Name ASC");
    }


    ///
    /// Fires when Update link is clicked
    ///

    ///
    ///
    protected void UpdateListViewItem(object sender, ListViewUpdateEventArgs e)
    {
        ListViewItem item = ListView1.Items[e.ItemIndex];
       
        int autoID = int.Parse(ListView1.DataKeys[e.ItemIndex].Value.ToString());

        TextBox tName = (TextBox)item.FindControl("txtName");
        TextBox tAddress = (TextBox)item.FindControl("txtAddress");
        TextBox tPhone = (TextBox)item.FindControl("txtPhone");

        // insert records into database
        using (SqlConnection conn = new SqlConnection(_connStr))
        {
            string Sql = "update Details set Name = @Name, Address = @Address, Phone = @Phone where AutoID = @AutoID";
            conn.Open();
            using (SqlCommand dCmd = new SqlCommand(Sql, conn))
            {
                dCmd.Parameters.AddWithValue("@AutoID", autoID);
                dCmd.Parameters.AddWithValue("@Name", tName.Text.Trim());
                dCmd.Parameters.AddWithValue("@Address", tAddress.Text.Trim());
                dCmd.Parameters.AddWithValue("@Phone", tPhone.Text.Trim());
                dCmd.ExecuteNonQuery();
            }
            conn.Close();
            lblMessage.Text = "Records Updated Successfully.";
        }

        ListView1.EditIndex = -1;
        // Rebind the details
        BindPersonDetails("Name ASC");
    }

    ///
    /// Fires when Cancel link is clicked
    ///

    ///
    ///
    protected void CancelListViewItem(object sender, ListViewCancelEventArgs e)
    {
        ListView1.EditIndex = -1;
        // Rebind the data
        BindPersonDetails("Name ASC");
    }

    ///
    /// Fires when Insert button is clicked
    ///

    ///
    ///
    protected void InsertListViewItem(object sender, ListViewInsertEventArgs e)
    {
        ListViewItem item = e.Item;
        TextBox tName = (TextBox) item.FindControl("txtName");
        TextBox tAddress = (TextBox)item.FindControl("txtAddress");
        TextBox tPhone = (TextBox)item.FindControl("txtPhone");

        // insert records into database
        using (SqlConnection conn = new SqlConnection(_connStr))
        {
            string Sql = "insert into Details (Name, Address, Phone) values " +
                " (@Name, @Address, @Phone)";
            conn.Open();
            using (SqlCommand dCmd = new SqlCommand(Sql, conn))
            {
                dCmd.Parameters.AddWithValue("@Name", tName.Text.Trim());
                dCmd.Parameters.AddWithValue("@Address", tAddress.Text.Trim());
                dCmd.Parameters.AddWithValue("@Phone", tPhone.Text.Trim());
                dCmd.ExecuteNonQuery();
            }
            conn.Close();
        }
        lblMessage.Text = "New Records Inserted Successfully.";
        // Rebind the details
        BindPersonDetails("Name ASC");
    }

    ///
    /// Fires when page links are clicked in the Page control
    ///

    ///
    ///
    protected void PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
    {
        DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
        // Rebind the data
        BindPersonDetails("Name ASC");
    }

    ///
    /// Fires when delete link is clicked
    ///

    ///
    ///
    protected void DeleteListViewItem(object sender, ListViewDeleteEventArgs e)
    {
        int autoID = int.Parse(ListView1.DataKeys[e.ItemIndex].Value.ToString());
       
        // insert records into database
        using (SqlConnection conn = new SqlConnection(_connStr))
        {
            string Sql = "delete from Details where AutoID = @AutoID";
            conn.Open();
            using (SqlCommand dCmd = new SqlCommand(Sql, conn))
            {
                dCmd.Parameters.AddWithValue("@AutoID", autoID);
                dCmd.ExecuteNonQuery();
            }
            conn.Close();
            lblMessage.Text = "Records Deleted Successfully.";
        }
        // Rebind the details
        BindPersonDetails("Name ASC");
    }

    ///
    /// Fires when column name is clicked
    ///

    ///
    ///
    protected void SortListViewRecords(object sender, ListViewSortEventArgs e)
    {
        string sortExpression = e.SortExpression + " " + e.SortDirection;
        BindPersonDetails(sortExpression);
    }

    ///
    /// Bind Person Details data
    ///

    private void BindPersonDetails(string sortExpression)
    {
        sortExpression = sortExpression.Replace("Ascending", "ASC");

        using (SqlConnection conn = new SqlConnection(_connStr))
        {
            conn.Open();
            using (SqlDataAdapter dAd = new SqlDataAdapter("select * from Details order by Name", conn))
            {
                DataTable dTable = new DataTable();
                dAd.Fill(dTable);
                // Sort now
                dTable.DefaultView.Sort = sortExpression;
                // Bind data now
                ListView1.DataSource = dTable;
                ListView1.DataBind();
            }
            conn.Close();
        }
    }