Pages

Thursday, August 20, 2009

LINQ: Building an IQueryable Provider - Part I

I’ve been meaning for a while to start up a series of posts that covers building LINQ providers using IQueryable. People have been asking me advice on doing this for quite some time now, whether through internal Microsoft email or questions on the forums or by cracking the encryption and mailing me directly. Of course, I’ve mostly replied with “I’m working on a sample that will show you everything” letting them know that soon all will be revealed. However, instead of just posting a full sample here I felt it prudent to go step by step so I can actual dive deep and explain everything that is going on instead of just dumping it all in your lap and letting you find your own way.

The first thing I ought to point out to you is that IQueryable has changed in Beta 2. It’s no longer just one interface, having been factored into two: IQueryable and IQueryProvider. Let’s just walk through these before we get to actually implementing them.

If you use Visual Studio to ‘go to definition’ you get something that looks like this:

 

public interface IQueryable : IEnumerable
{

Type ElementType { get; }

Expression Expression { get; }

IQueryProvider Provider { get; }

}

public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable
{

}

Of course, IQueryable no longer looks all that interesting; the good stuff has been pushed off into the new interface IQueryProvider. Yet before I get into that, IQueryable is still worth looking at. As you can see the only things IQueryable has are three read-only properties. The first one gives you the element type (or the ‘T’ in IQueryable<T>). It’s important to note that all classes that implement IQueryable must also implement IQueryable<T> for some T and vice versa. The generic IQueryable<T> is the one you use most often in method signatures and the like. The non-generic IQueryable exist primarily to give you a weakly typed entry point primarily for dynamic query building scenarios.

The second property gives you the expression that corresponds to the query. This is quintessential essence of IQueryable’s being. The actual ‘query’ underneath the hood of an IQueryable is an expression that represents the query as a tree of LINQ query operators/method calls. This is the part of the IQueryable that your provider must comprehend in order to do anything useful. If you look deeper you will see that the whole IQueryable infrastructure (including the System.Linq.Queryable version of LINQ standard query operators) is just a mechanism to auto-construct expression tree nodes for you. When you use the Queryable.Where method to apply a filter to an IQueryable, it simply builds you a new IQueryable adding a method-call expression node on top of the tree representing the call you just made to Queryable.Where. Don’t believe me? Try it yourself and see what it does.

Now that just leaves us with the last property that gives us an instance of this new interface IQueryProvider. What we’ve done is move all the methods that implement constructing new IQueryables and executing them off into a separate interface that more logically represents your true provider.

public interface IQueryProvider
{

IQueryable CreateQuery(Expression expression);

IQueryable<TElement> CreateQuery<TElement>(Expression expression);

object Execute(Expression expression);

TResult Execute<TResult>(Expression expression);

}

Looking at the IQueryProvider interface you might be thinking, “why all these methods?” The truth is that there are really only two operations, CreateQuery and Execute, we just have both a generic and a non-generic form of each. The generic forms are used most often when you write queries directly in the programming language and perform better since we can avoid using reflection to construct instances.

The CreateQuery method does exactly what it sounds like it does. It creates a new instance of an IQueryable query based on the specified expression tree. When someone calls this method they are basically asking your provider to build a new instance of an IQueryable that when enumerated will invoke your query provider and process this specific query expression. The Queryable form of the standard query operators use this method to construct new IQueryable’s that stay associated with your provider. Note the caller can pass any expression tree possible to this API. It may not even be a legal query for your provider. However, the only thing that must be true is that expression itself must be typed to return/produce a correctly typed IQueryable. You see the IQueryable contains an expression that represents a snippet of code that if turned into actual code and executed would reconstruct that very same IQueryable (or its equivalent).

The Execute method is the entry point into your provider for actually executing query expressions. Having an explicit execute instead of just relying on IEnumerable.GetEnumerator() is important because it allows execution of expressions that do not necessarily yield sequences. For example, the query “myquery.Count()” returns a single integer. The expression tree for this query is a method call to the Count method that returns the integer. The Queryable.Count method (as well as the other aggregates and the like) use this method to execute the query ‘right now’.

There, that doesn’t seem so frightening does it? You could implement all those methods easily, right? Sure you could, but why bother. I’ll do it for you. Well all except for the execute method. I’ll show you how to do that in a later post.

First let’s start with the IQuerayble. Since this interface has been split into two, it’s now possible to implement the IQueryable part just once and re-use it for any provider. I’ll implement a class called Query<T> that implements IQueryable<T> and all the rest.

public class Query<T> : IQueryable<T>, IQueryable, IEnumerable<T>, IEnumerable, IOrderedQueryable<T>, IOrderedQueryable
{

QueryProvider provider;

Expression expression;



public Query(QueryProvider provider)
{

if (provider == null)
{

throw new ArgumentNullException("provider");

}

this.provider = provider;

this.expression = Expression.Constant(this);

}



public Query(QueryProvider provider, Expression expression)
{

if (provider == null)
{

throw new ArgumentNullException("provider");

}

if (expression == null)
{

throw new ArgumentNullException("expression");

}

if (!typeof(IQueryable<T>).IsAssignableFrom(expression.Type))
{

throw new ArgumentOutOfRangeException("expression");

}

this.provider = provider;

this.expression = expression;

}



Expression IQueryable.Expression
{

get { return this.expression; }

}



Type IQueryable.ElementType
{

get { return typeof(T); }

}



IQueryProvider IQueryable.Provider
{

get { return this.provider; }

}



public IEnumerator<T> GetEnumerator()
{

return ((IEnumerable<T>)this.provider.Execute(this.expression)).GetEnumerator();

}



IEnumerator IEnumerable.GetEnumerator()
{

return ((IEnumerable)this.provider.Execute(this.expression)).GetEnumerator();

}



public override string ToString()
{

return this.provider.GetQueryText(this.expression);

}

}

As you can see now, the IQueryable implementation is straightforward. This little object really does just hold onto an expression tree and a provider instance. The provider is where it really gets juicy.

Okay, now I need some provider to show you. I’ve implemented an abstract base class called QueryProvider that Query<T> referred to above. A real provider can just derive from this class and implement the Execute method.

public abstract class QueryProvider : IQueryProvider
{

protected QueryProvider()
{

}



IQueryable<S> IQueryProvider.CreateQuery<S>(Expression expression)
{

return new Query<S>(this, expression);

}



IQueryable IQueryProvider.CreateQuery(Expression expression)
{

Type elementType = TypeSystem.GetElementType(expression.Type);

try
{

return (IQueryable)Activator.CreateInstance(typeof(Query<>).MakeGenericType(elementType), new object[] { this, expression });

}

catch (TargetInvocationException tie)
{

throw tie.InnerException;

}

}



S IQueryProvider.Execute<S>(Expression expression)
{

return (S)this.Execute(expression);

}



object IQueryProvider.Execute(Expression expression)
{

return this.Execute(expression);

}



public abstract string GetQueryText(Expression expression);

public abstract object Execute(Expression expression);

}

I’ve implemented the IQueryProvider interface on my base class QueryProvider. The CreateQuery methods create new instances of Query<T> and the Execute methods forward execution to this great new and not-yet-implemented Execute method.

I suppose you can think of this as boilerplate code you have to write just to get started building a LINQ IQueryable provider. The real action happens inside the Execute method. That’s where your provider has the opportunity to make sense of the query by examining the expression tree.

And that’s what I’ll start showing next time.

UPDATE:

It looks like I’ve forget to define a little helper class my implementation was using, so here it is:

internal static class TypeSystem
{

internal static Type GetElementType(Type seqType)
{

Type ienum = FindIEnumerable(seqType);

if (ienum == null) return seqType;

return ienum.GetGenericArguments()[0];

}

private static Type FindIEnumerable(Type seqType)
{

if (seqType == null || seqType == typeof(string))

return null;

if (seqType.IsArray)

return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType());

if (seqType.IsGenericType)
{

foreach (Type arg in seqType.GetGenericArguments())
{

Type ienum = typeof(IEnumerable<>).MakeGenericType(arg);

if (ienum.IsAssignableFrom(seqType))
{

return ienum;

}

}

}

Type[] ifaces = seqType.GetInterfaces();

if (ifaces != null && ifaces.Length > 0)
{

foreach (Type iface in ifaces)
{

Type ienum = FindIEnumerable(iface);

if (ienum != null) return ienum;

}

}

if (seqType.BaseType != null && seqType.BaseType != typeof(object))
{

return FindIEnumerable(seqType.BaseType);

}

return null;

}

}
Yah, I know. There’s more ‘code’ in this helper than in all the rest. Sigh. J

Original post can be found here

Sunday, August 16, 2009

A Defense of Reflection in .NET

Nick Harrison

A Defense of Reflection in .NET

13 August 2009

by Nick Harrison

The trouble with making general rules about programming practices is that one can miss out on many benefits of of a framework by following them too literally in every context. Everyone knows that one should watch for performance problems and security issues with reflection. It doesn't mean you shouldn't it, it just means you must test carefully, monitor performance, and assess risks. Nick Harrison illustrates the theme with a practical example.

Introduction

Reflection is one of the great marvels of modern programming environments.   Being able to store meta data about our code, and retrieve it at run time, opens up a world of possibilities.   Many developers and software designers have embraced reflection and sing its praises, but reflection is not without its critics.

Here we will explore some of the criticism of reflection, debunk some of the myths around its usage, and explore the benefits through some practical applications.

What's Wrong With Reflection

There are various complaints and cautionary warnings against using reflection.  Some of these are valid risks that we need to be aware of;  others are wild tales based on early-adopters not understanding what they were using.  Some are valid only in certain circumstances, or valid in all but special cases.  Here we will explore some of these complaints.   You should always be wary of a technology that is new or not well understood, but do not let that stand in the way of making appropriate use of technology.

Performance

Everyone knows that reflection is slow.   The web is full of well meaning warnings that one should not use Reflection if you care about performance.   Retrieving the meta-data slows your application down: One is often reading advice that, If you care about performance, you should never use reflection.  

This is a legitimate concern that should be taken seriously, but this is not a carte blanche reason not to ever use Reflection.

While you should always worry about performance, you should not let performance worries keep you from making appropriate use of new technology.   Do your own timing studies in your own environment.  If there are performance issues, there are ways to minimize the performance impact.

The DotNet framework itself uses reflection extensively.  Reflection is being used whether we intend to or not.   Take a look at the details in the Machine.Config file.  Almost all that you see is providing details to open an Assembly and load a Type with Reflection to make the framework itself work.  The DotNet framework is all about Reflection.

If performance worries still nag you, there are tweaks that you can make in your own code to improve performance.

If you are going to make repeated calls to the Properties of an object, cache the Properties in a Hash Table.  Reference the hash table instead of repeated calls to GetProperty or GetProperties.  The same is true for Methods, Types and Assemblies.

Get comfortable with the BindingFlags enumeration.  Always specify BindingFlags.  Never use the IgnoreCase flag.  Limit the searches to Public.   Limit the searches to Static or Instance as appropriate.

Don't just assume that performance will suffer.   Embrace Reflection, but test it.   There are various profiling tools, such as Red Gate's Ants Profiler.   Use them to identify the true cause of a performance problem.   If Reflection is the right tool, don't ignore it simply because someone told you that it will be slow.  If it turns out be too slow for you, there are ways to optimize its usage.

Security

Reflection, it is said,  poses an unacceptable security risk.   The essence of most designs that leverage Reflection also incorporate the process of dynamically discovering new code and executing it.   This opens up a risk that malicious code will be executing and compromising the entire system.

In the modern world of Malware and security threats, we are all concerned about security.   The risk with Reflection is that malicious code may be substituted for your own code.   Many reflective designs do, indeed, rely on loading new assemblies, discovering new types, and running discovered methods and properties on these new types.  While this may lead many to steer clear of a reflective solution, don't run scared.

An intruder would need to physically place malicious code where your reflective code can find it.   While this is not impossible, a good defense in depth design can mitigate this risk.   Properly configured firewalls with processing servers behind the firewalls will help.  Intrusion detection will alert administrators to servers that are being targeted, and properly patched servers will help eliminate known vulnerabilities.

Code Access Security, properly configured, can also limit the access that reflective code has.   With Code Access Security, individual assemblies can run with fewer rights than the user running the assembly.

This article is not about configuring security settings but rather to assure you that there are counter measures to any security concern that you may have.

Confusion

Reflective code, so one hears,  is very hard to follow.   Developers new to the project will have difficulty learning the ropes.  Anything that steepens the learning curve jeopardizes project time lines and should be avoided.  If only a select group of developers can understand the reflective code then the project is overly dependent on this select group, and is doomed to fail.

This is also not a very legitimate concern.   If every design decision is based on what the least experienced programmer can readily understand, our designs will be severely limited.   Reflective code can, and should, be isolated.   Daily development should not be modifying this code.   Daily development should use the reflective methods to simplify daily development tasks. 

We want our code to be easy to follow, and Reflective code is not always the most intuitive code to understand at first glance.    Without a doubt the hard-coded option is easier to follow than the reflective version

 

Hard Coded

 

public void MapData(IEmployee first, IEmployee second)

{

second.FirstName = first.FirstName;

second.Address = first.Address;

second.BranchLocation = first.BranchLocation;

. . .

}

Reflective

public static void MapData(object sourceObject,

object targetObject)

{

object[] value = new object[1];

object[] param = new object[0];

foreach (PropertyInfo propertyInfo

in sourceObject.GetType().GetProperties())

{

PropertyInfo targetPropertyInfo =

targetObject.GetType().

GetProperty(propertyInfo.Name);

if (targetPropertyInfo.CanWrite)

{

value[0] = propertyInfo.GetValue(sourceObject,

BindingFlags.Public, null, null, null);

targetPropertyInfo.SetValue

(targetObject, value,null);

}

}

}

 


Anyone can look at the hard-coded version and immediately tell what is going on.   The reflective version will probably take a senior developer a second look to figure out.

However, the hard-coded version is tedious code.  Depending on the number of properties being mapped, more and more errors are likely to be introduced.  In the long run, this results in  more code that has to be hand written.

While the reflective code may be hard to follow, it does not need to be referenced very often to be useful.

With the hard-coded implementation, you have to write a similar method for every type that you want to map.  This is a tedious proposition indeed!   With the reflective implementation, this one method can handle the process of mapping any object in your system.

For the observant reader, this is far from the most optimized implementation for the reflective version.  We will go over the reflective version in more detail later and discuss various ways to optimize.

Why Use Reflection?


Developer Performance


As mentioned earlier, the hard coded version is often tedious, and tedious code is often error-prone.

You can well imagine the potential for introducing bugs by having to iterate through, and explicitly set, each property in an object. This can quickly get out of hand.   Bugs from assigning the wrong value to the wrong property are easy to introduce and difficult to track down.

It is much easier to write a single line of code to handle the mapping and then move on to more important tasks such as implementing business logic and meeting deadlines.

A call like DataMapper.CopyTo (data, ui) is easy to understand and quick to write.   As long as the property names match and are of the same types, you don't have to worry about missing any assignments.   As a developer, you implement a series of rather simple properties to handle validation, and you don't have to get bogged down in the details of the mapping logic.

Stability / Consistency


Not everyone will get reflective code right the first time, but this is the beauty of consistency.  If the implementation that everyone is using is inefficient or has a logic problem, you have only to correct it in one place.   If there are multiple hard coded implementations, some will, no doubt, be done as efficiently as possible.   Some will, to be sure, be free from all logic problems, but at least some implementations will have problems that will need to be addressed.

Reflective code is much easier to reuse.   If the code is widely reused, then we have fewer places to correct when there is a problem found.

This consistency improves the overall stability of the system.

Practical Applications


Tweaking Performance


Performance is always a concern.   There are some simple steps that we can take to eke  the best performance out of our reflective code.

Whenever you make a Reflection call, make it count.  Cache the output so that it can be reused.   Calls to GetProperty, LoadAssembly or GetType are expensive.   If there is any chance that you are going to need a method or a property more than once, store the return value so that you can use it later without having to make the call again.  

This is also an example where multi threading can give you the perception of performance improvement.   This proves to be a nice option for batch application and for business / data servers.   This does not provide any benefit for the web UI, but can be very beneficial for a traditional windows application.

CopyTo


CopyTo is the reflective MapData that we saw earlier.   Let's discuss some strategies to get the basic method ready for prime-time.   As we stated earlier, we don't want to throw away the return value of the GetProperty call.   We also want to avoid calling GetProperty altogether when we are truly interested in every property.

We start by checking to see if our collection of properties has already been loaded into a hash table.  If they have, then we use this previously-loaded list.   If not, we go ahead and load the details into the hash table.  This will allow us to avoid the GetProperty calls altogether.   If we are copying from one object to another of the same type, we dramatically reduce the number of reflection calls.  If we call this method multiple times with the same set of objects, we reduce the reflective even more.

Our caching logic could look similar to this:

 

private Hashtable properties;

private Hashtable Properties

{

get

{

if (properties == null)

properties = new Hashtable();

return properties;

}

}



private void LoadProperties(object targetObject, Type targetType)

{

if (properties[targetType.FullName] != null)

{

List<PropertyInfo> propertyList = new List<PropertyInfo>();

PropertyInfo[] objectProperties =

targetType.GetProperties(BindingFlags.Public);

foreach (PropertyInfo currentProperty in objectProperties)

{

propertyList.Add(currentProperty);

}

properties[targetObject] = propertyList;

}

}

Here we first check to see if the Hash table already has a list of properties for our object.   If it does then we have nothing to do.   If not, we load the properties into a generic list to be added to the hash table.

Our optimized CopyTo function can now be rewritten as:

 

public  void CopyTo(object sourceObject, object targetObject)

{

object[] value = new object[1];

Type sourceType = sourceObject.GetType();

Type targetType = targetObject.GetType();



LoadProperties(sourceObject, sourceType);

LoadProperties(targetObject, targetType);

List<PropertyInfo> sourcePoperties =

Properties[sourceType.FullName] as List<PropertyInfo>;

List<PropertyInfo> targetProperties =

Properties[targetType.FullName] as List<PropertyInfo>;



foreach (PropertyInfo sourceProperty in sourcePoperties)

{

PropertyInfo targetPropertyInfo = targetProperties.

Find(delegate(PropertyInfo prop)

{ return prop.Name == sourceProperty.Name ; });

if (sourceProperty.CanRead)

{

if (targetPropertyInfo.CanWrite)

{

value[0] = sourceProperty.GetValue(sourceObject,

BindingFlags.Public, null, null, null);

targetPropertyInfo.SetValue

(targetObject, value, null);

}

}

}

}

The biggest change we have here is in the calls to the LoadProperties method.   If the properties are already loaded, this will have no effect.   If they are not, this method will load the properties for us.  Once our properties are loaded into the hash table, we can safely pull them out of the generic list instead of making repeated calls to GetProperties or GetProperty.

Once we have our two properties, we make sure that the source can be read and that the target can be written to.   Now we simply “get” the value from the source and “set” the value on the target.

MapDataToBusinessEntityCollection


MapDataToBusinessEntityCollection is a generic Reflective method.  We pass in the data-type for the objects to be mapped as a generic parameter along with a data reader.   We use reflection to find the properties in this type and we use the meta data in the DataReader to find the fields.

Whenever we find a field from the data reader that has a matching writable property in the generic type, we pull the value from the DataReader and assign it to a newly created object.   Regardless of how many properties are in T, this method will map every property that has a matching field in the DataReader.  Any properties that are not in the DataReader will be unmapped.  Any fields in the data reader that do not have a matching property will be ignored.   The validation logic is handled in the implementation of the properties in T.

public staticList<T> MapDataToBusinessEntityCollection<T>

(IDataReader dr)

   where T : new()

{

  Type businessEntityType = typeof (T);

  List<T> entitys = newList<T>();

  Hashtable hashtable = newHashtable();

  PropertyInfo[] properties = businessEntityType.GetProperties();

  foreach (PropertyInfo info inproperties)

  {

      hashtable[info.Name.ToUpper()] = info;

  }

  while(dr.Read())

  {

      T newObject = newT();

      for(int index = 0; index < dr.FieldCount; index++)

      {

          PropertyInfo info = (PropertyInfo)

                              hashtable[dr.GetName(index).ToUpper()];

          if((info != null) && info.CanWrite)

          {

              info.SetValue(newObject, dr.GetValue(index), null);

          }

      }

      entitys.Add(newObject);

  }

  dr.Close();

  returnentitys;

}


Timing Studies


To evaluate the performance implications of this approach, I set up a test-bed to perform my own timing studies.   An ounce of testing is worth a pound of speculation.

In my test-bed, I defined an object to encapsulate the Employee table in the NorthWinds database.   I loaded this table with 100,000 records and timed how long it took to retrieve records using various methods.

777-ADefen1 


Hardcoded, is this case, is the worse way you can write a Hard-coded  implementation, but it is also an approach that I have commonly seen followed.

private void HardCoded()

{

System.DateTime start = DateTime.Now;

System.Data.IDataReader dr = GetData(recordCount);

while (dr.Read())

{

CustomTypes.Employees newEmployee =

new CustomTypes.Employees();

newEmployee.Address = dr["Address"].ToString();

newEmployee.BirthDate =

DateTime.Parse(dr["BirthDate"].ToString());

newEmployee.City = dr["City"].ToString();

newEmployee.Country = dr["Country"].ToString();

newEmployee.EmployeeID = Int32.Parse(dr["EmployeeID"].ToString());

newEmployee.Extension = dr["Extension"].ToString();

newEmployee.FirstName = dr["FirstName"].ToString();

newEmployee.HireDate = DateTime.Parse(dr["HireDate"].ToString());

newEmployee.LastName = dr["LastName"].ToString();

newEmployee.PostalCode = dr["PostalCode"].ToString();

newEmployee.Region = dr["Region"].ToString();

newEmployee.ReportsTo = Int32.Parse(dr["ReportsTo"].ToString());

newEmployee.Title = dr["Title"].ToString();

newEmployee.TitleOfCourtesy = dr["TitleOfCourtesy"].ToString();

pgbHardCodedConversion.Increment(1);

}

dr.Close();

System.DateTime stop = DateTime.Now;

System.TimeSpan ts = new TimeSpan(stop.Ticks - start.Ticks);

lblHardCodedConvertedTime.Text = "Finished in "

+ ts.TotalMilliseconds + " milliseconds";

}

This has several obvious problems, but since it has to be re coded for every data reader, it will often be done poorly.

Reflective Singleton is the same method outlined above, but without caching the PropertyInfo objects.   Comparing the Reflective Singleton and the ReflectiveBatch shows the benefits of caching the PropertyInfo objects.   I believe this to be a dramatic improvement.

Hard-Coded without Conversion is the same as the HardCoded implementation but skips the extra ToString and parsing operations which should never be performed anyway.

So why is the Reflective Batch implementation faster than the hard-coded version?   Indexing into the DataReader by Name is also a slow operation.   The Reflective implementation avoids this costly lookup.

Undoubtedly, caching the indexes into the DataReader will change the results.   More properties in the test object will change the results, and there are probably more optimizations that could be done to the hard-coded implementation.

All of this reinforces the need to test in your own environment.  Test for yourself.   You may be surprised that a reflective solution probably will not ruin performance, and it will shorten your time to market.

Conclusion


Do not shy away from Reflection or any other technology just because of warnings that you hear.  Always verify that the warnings apply to your project.   Often times, they will not.

If you are worried about performance concerns, don’t blindly follow someone else’s opinion.  Test it with your own application.

Above all don’t be afraid to learn something new!

Nick Harrison

Author profile: Nick Harrison

Nick Harrison is a Software Architect and .NET advocate in Columbia, SC. Nick has over 14 years experience in software developing, starting with Unix system programming and then progressing to the DotNet platform. You can read his blog as www.geekswithblogs.net/nharrison

Search for other articles by Nick Harrison

Free ebook on C# 3.0

C# 3.0 Pocket Reference

This book is for busy programmers who want a succinct and yet readable guide to C# 3.0 and LINQ.
C# 3.0 Pocket Reference,
written by Joseph and Ben Albahari, tells you exactly what you need to know, without long introductions or bloated samples. Boost your C# expertise and keep ahead of your peers!

 

Boost your C# expertise:
Download your free ebook here
and keep ahead of the game.

Wednesday, August 12, 2009

Custom Persister to store the state in a backend database

As requested in this post, following is an example of a way to store viewstate in a database on the server instead of the hidden form field on the page. The form only maintains a guid that is used to retrieve saved viewstate from the DB. This can reduce bandwidth considerably if viewstate is something that you can't or don't want to disable completely.

The following code snippets are included:

  • SamplePageStatePersister.cs - custom mechanism for loading and saving viewstate for the page.

  • SamplePageAdapter.cs - returns a new instance of SamplePageStatePersister (this is enlisted by the App.Browser file).

  • App.Browser - must be added to the web project and tells the web application to use our custom page adapter.

  • PageViewStateServices.cs - handles the interaction with the database via stored procedures to optimise performance.

  • PageViewState.sql - creates the table to hold the view state and the stored procedures to interact with the database. You will need to apply the appropriate permissions.

  • CleanupPageViewState.sql - deletes old view state to stop the database growing uncontrollably. Configure as a scheduled job and can be modified to extend or reduce the time window for view state being maintained in the database. Defaults to 4 hours.

NOTE: This current example will not work if you use Server.Transfer and carry across the form data in the transfer. In this case, the view state ID will be carried across too and then subsequent back navigation will result in an error.

SamplePageStatePersister.cs

using System;
using System.Globalization;
using System.IO;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/// <summary>
///
---------------------------------------------------
/// This class is the page state persister for the application.
///
///
Created by Jason Hill on 26/6/2007.
/// ---------------------------------------------------
/// </summary>
public class SamplePageStatePersister : System.Web.UI.PageStatePersister
{

private Page _page;

/// ---------------------------------------------------
/// <summary>
///
Constructor.
/// </summary>
/// <remarks>
/// <author>
jhill</author>
/// <creation>
Wednesday, 30 May 2007</creation>
/// </remarks>
/// <param name="page">
Page.</param>
///
-----------------------------------------------
public SamplePageStatePersister(Page page)
: base(page)
{
_page = page;
}

/// ----------------------------------------------- /// <summary>
///
Get the unique ID for the view state.
/// </summary>
/// <remarks>
/// <author>
jhill</author>
/// <creation>
Wednesday, 30 May 2007</creation>
/// </remarks>
///
-----------------------------------------------
    private Guid GetViewStateID()
{
string viewStateKey;

// Get the ID from the request
viewStateKey = _page.Request["__VIEWSTATEID"];

// Assign a new ID if we don't have one in the request
if (string.IsNullOrEmpty(viewStateKey))
{
return Guid.NewGuid();
}

// Use the ID from the request if it is valid, else assign a new ID
try
{
return new Guid(viewStateKey);
}
catch (FormatException)
{
return Guid.NewGuid();
}

}

/// -----------------------------------------------
/// <summary>
///
Load the view state from persistent medium.
/// </summary>
/// <remarks>
/// <author>
jhill</author>
/// <creation>
Wednesday, 30 May 2007</creation>
/// </remarks>
///
-----------------------------------------------
public override void Load()
{

// Load view state from DB
string pageViewState = PageViewStateServices.GetByID(GetViewStateID());

if (pageViewState == null)
{
ViewState = null;
ControlState = null;
}
else
{

// Deserialize into a Pair of ViewState and ControlState objects
IStateFormatter formatter = StateFormatter;
Pair statePair = (Pair)formatter.Deserialize(pageViewState);

// Update ViewState and ControlState
ViewState = statePair.First;
ControlState = statePair.Second;
}

}

/// -----------------------------------------------
/// <summary>
///
Save the view state to persistent medium.
/// </summary>
/// <remarks>
/// <author>
jhill</author>
/// <creation>
Wednesday, 30 May 2007</creation>
/// </remarks>
/// <param name="viewState">
View state to save.</param>
///
-----------------------------------------------
public override void Save()
{

// Create a pair for ViewState and ControlState
Pair statePair = new Pair(ViewState, ControlState);
IStateFormatter formatter = StateFormatter;

// Save the view state
Guid id = GetViewStateID();
PageViewStateServices.Save(id, formatter.Serialize(statePair));

// Store the ID of the view state in a hidden form field
HtmlInputHidden control = _page.FindControl("__VIEWSTATEID") as HtmlInputHidden;
if (control == null)
{
ScriptManager.RegisterHiddenField(_page, "__VIEWSTATEID", id.ToString());
}
else
{
control.Value = id.ToString();
}

}


}
 
SamplePageAdapter.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/// <summary>
///
-----------------------------------------------
/// This class is the page adapter for the application.
///
///
Created by Jason Hill on 26/6/2007.
/// -----------------------------------------------
/// </summary>
public class SamplePageAdapter : System.Web.UI.Adapters.PageAdapter
{

/// -------------------------------------------
/// <summary>
///
Gets the state persister for the page.
/// </summary>
/// <remarks>
/// <author>
jhill</author>
/// <creation>
Wednesday, 30 May 2007</creation>
/// </remarks>
///
-------------------------------------------
public override PageStatePersister GetStatePersister()
{
return new SamplePageStatePersister(Page);
}

}

 

App.Browser
<browsers>
<
browser refID="Default">
<
controlAdapters>
<
adapter controlType="System.Web.UI.Page" adapterType="SamplePageAdapter" />
</
controlAdapters>
</
browser>
</
browsers>

 


 

PageViewStateServices.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections;
using System.Text;

/// <summary>
///
--------------------------------------------------------
/// This class provides services for handling page view state.
///
///
Created by Jason Hill on 26/6/2007.
/// --------------------------------------------------------
/// </summary>
public static class PageViewStateServices
{

/// ----------------------------------------------------
/// <summary>
///
Get a page view state by ID.
/// </summary>
/// <remarks>
/// <author>
jhill</author>
/// <creation>
Wednesday, 30 May 2007</creation>
/// </remarks>
/// <param name="id">
ID.</param>
///
----------------------------------------------------
public static string GetByID(Guid id)
{

using (SqlConnection connection = new SqlConnection(Common.PageViewStateConnectionString))
{
connection.Open();

try
{
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetByID";
command.Parameters.Add(new SqlParameter("@id", id));
return (string)command.ExecuteScalar();
}
}

finally
{
connection.Close();
}
}

}

/// ----------------------------------------------
/// <summary>
///
Save the view state.
/// </summary>
/// <remarks>
/// <author>
jhill</author>
/// <creation>
Wednesday, 30 May 2007</creation>
/// </remarks>
/// <param name="id">
Unique ID.</param>
/// <param name="value">
View state value.</param>
///
----------------------------------------------
public static void Save(Guid id, string value)
{

using (SqlConnection connection = new SqlConnection(Common.PageViewStateConnectionString))
{
connection.Open();

try
{

using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "SaveViewState";
command.Parameters.Add(new SqlParameter("@id", id));
command.Parameters.Add(new SqlParameter("@value", value));
command.ExecuteNonQuery();
}

}

finally
{
connection.Close();
}
}

}

}

 


 

PageViewState.sql
 
   1:  SET ANSI_NULLS ON
   2:  GO
   3:  SET QUOTED_IDENTIFIER ON
   4:  GO
   5:  CREATE TABLE [dbo].[PageViewState](
   6:      [ID] [uniqueidentifier] NOT NULL,
   7:      [Value] [text] NOT NULL,
   8:      [LastUpdatedOn] [datetime] NOT NULL,
   9:   CONSTRAINT [PK_PageViewState] PRIMARY KEY CLUSTERED 
  10:  (
  11:      [ID] ASC
  12:  )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  13:  ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
  14:  GO
  15:   
  16:  SET ANSI_NULLS ON
  17:  GO
  18:  SET QUOTED_IDENTIFIER ON
  19:  GO
  20:  CREATE PROCEDURE [dbo].[GetByID] 
  21:      @id uniqueidentifier 
  22:  AS
  23:  BEGIN
  24:      SET NOCOUNT ON;
  25:      
  26:      select Value
  27:      from PageViewState
  28:      where ID = @id
  29:   
  30:  END
  31:   
  32:  GO
  33:  SET ANSI_NULLS ON
  34:  GO
  35:  SET QUOTED_IDENTIFIER ON
  36:  GO
  37:  CREATE PROCEDURE [dbo].[SaveViewState]
  38:      @id uniqueidentifier, 
  39:      @value text
  40:  AS
  41:  BEGIN
  42:      SET NOCOUNT ON;
  43:      
  44:      if (exists(select ID from PageViewState where ID = @id))
  45:          update PageViewState
  46:          set Value = @value, LastUpdatedOn = getdate()
  47:          where ID = @id
  48:      else
  49:          insert into PageViewState
  50:          (ID, Value, LastUpdatedOn)
  51:          values (@id, @value, getdate())
  52:   
  53:  END
  54:   
  55:   
 
 
CleanupPageViewState.sql
 
   1:  delete from PageViewState
   2:  where LastUpdatedOn < dateadd(minute, -240, current_timestamp)

 


Original post can be found here

 

Monday, August 10, 2009

.NET: Getting the Path of the Executing Assembly

To retrieve the path of the executing assembly (the VB 6.0 equivalent of App.Path), use the following code:

[C#]
String strPath = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().CodeBase);

[Visual Basic]
Dim strPath As String = System.IO.Path.GetDirectoryName( _
System.Reflection.Assembly.GetExecutingAssembly().CodeBase)

 


Original post can be found here

.NET: Retrieving Assembly Attributes

To retrieve the value set in the Assembly Attributes in the AssemblyInfo.cs or AssemblyInfo.vb file, use the code below. The example shows retrieving the AssemblyDescription attribute.

 

[C#]
private static readonly string strAssemblyDescription =
((AssemblyDescriptionAttribute)
Assembly.GetExecutingAssembly().GetCustomAttributes(
typeof(AssemblyDescriptionAttribute), false)[0]).Description;

[Visual Basic]
Private ReadOnly strAssemblyDescription As String = _
CType([Assembly].GetExecutingAssembly().GetCustomAttributes( _
GetType(AssemblyDescriptionAttribute), False), _
AssemblyDescriptionAttribute())(0).Description

 


Original post can be found here

Wednesday, August 5, 2009

SQL SERVER – Get Time in Hour:Minute Format from a Datetime – Get Date Part Only from Datetime

I have seen scores of expert developers getting perplexed with SQL Server in finding time only from datetime datatype. Let us have a quick glance look at the solution.

SQL Server 2000/2005

   1:  SELECT
   2:  CONVERT(VARCHAR(8),GETDATE(),108) AS HourMinuteSecond,
   3:  CONVERT(VARCHAR(8),GETDATE(),101) AS DateOnly
   4:  GO




SQL Server 2008

   1:  SELECT
   2:  CONVERT(TIME,GETDATE()) AS HourMinuteSecond,
   3:  CONVERT(DATE,GETDATE(),101) AS DateOnly
   4:  GO




I hope the above solution is clear to you all.

Reference : Pinal Dave (http://blog.SQLAuthority.com)