Archive

Archive for May, 2010

ASP.NET 4 Breaking Changes #2: LinqToSQL char becomes string

May 22, 2010 2 comments

If you are using LinqToSql instead of Entity Framework, you will notice (read compilation errors) that there are come about when you use VS2010 to regenerate the DBML file.

One of these is the fact that previously varchar(1) maps to char, but now it maps to string with a validation check for length > 1.

This will definitely cause errors during compilation especially when you have been using char comparison.

There are 2 ways to resolve this

1. Change the db from varchar(1) to char(1), this will render the dbml correctly as char 1 (Preferred method)

2. Change your code to handle this. but since this is now a string, you will have to make quite a fair bit of changes to ensure you do not put in more than 1 character inside this string. there’s also performance issues since char is always faster in comparison as compared to a string type

Categories: Uncategorized

SQL Server 2008 R2 is out!

May 4, 2010 Leave a comment

For those with MSDN, you can login to download the latest version of SQL Server 2008 R2 now!

Categories: Uncategorized

Simple and Useful ToString

May 3, 2010 Leave a comment

There’s many cases where the default tostring just does not cut it. Returning the type of the object is useless when used in debugging.

In such cases, you can use the below code to automatically return you all the properties of the object.

This code uses reflection to get a reference to all the public/private instance properties and builds up a html table structure to list out the properties and values. It is able to drill down even for dictionary and enumerable properties.

You can either have your class inherit this base class for automatic ToString functionality or else call the static ToStringObject function to convert any object to all its properties.

IMPORTANT: As this code will recursively iterate thru all the properties, if you are passing a LINQ or EF entity, please make sure to either set the drill level, or else disable lazyloading or set to read only data context, else all relations will be queried, iterated!


    public class GlobalToStringObject : INotifyPropertyChanged
    {
        public GlobalToStringObject() { }
        public static string ToStringObject(object o, int DrillLevel = 2, HashSet<object> CurrentObjects = null)
        {
            if (DrillLevel < 0)
            {
                return Typecast.ToString(o);
            }
            else
            {
                var sb = new StringBuilder();

                if (CurrentObjects == null)
                    CurrentObjects = new HashSet<object>();

                //Get the base type of this object
                var oType = o.GetType();

                sb.Append(“<table border=’1′>”);

                //Do the Properties
                var propertyInfos = o.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

                // sort properties by name
                Array.Sort(propertyInfos, delegate(PropertyInfo propertyInfo1, PropertyInfo propertyInfo2) { return propertyInfo1.Name.CompareTo(propertyInfo2.Name); });

                // write property names
                foreach (var propertyInfo in propertyInfos)
                {
                    sb.Append(“<tr valign=’top’><td>”);
                    sb.Append(propertyInfo.Name);
                    sb.Append(“</td><td>”);
                    try
                    {
                        var obj = propertyInfo.GetValue(o, null);

                        //process the property itself (recursive)
                        CheckAndProcessType(obj, sb, DrillLevel, CurrentObjects);
                    }
                    catch (Exception ex)
                    {
                        sb.Append(ex.ToString());
                    }
                    sb.Append(“</td></tr>”);
                }
                sb.Append(“</table>”);

                return sb.ToString();
            }
        }

        public static void CheckAndProcessType(object obj, StringBuilder sb, int DrillLevel, HashSet<object> CurrentObjects, bool IgnoreSelf = false)
        {
            if (DrillLevel < 0)
            {
                sb.Append(Typecast.ToString(obj));
            }
            else
            {
                bool isEnumerable = false;
                bool isDictionary = false;
                bool isPrimitive = false;
                bool isNull = false;
                #region Check Type
                if (obj == null)
                {
                    //null object can ignore
                    isNull = true;
                }
                else if (obj.GetType() == typeof(string))
                {
                    //string actually implements ienumerable, so need this check to make sure it does not cross to the next check
                    isPrimitive = true;
                }
                else if (obj.GetType().IsPrimitive)
                {
                    //check if is primitive type
                    isPrimitive = true;
                }
                else
                {
                    //Check if the type is a dictionary or ienumerable
                    foreach (var T in obj.GetType().GetInterfaces())
                    {
                        if (T.UnderlyingSystemType == typeof(IDictionary))
                        {
                            isDictionary = true;
                            break;
                        }
                        else if (T.UnderlyingSystemType == typeof(IEnumerable))
                        {
                            isEnumerable = true;
                        }
                    }
                }
                #endregion

                if (isNull)
                {
                    sb.Append(“&nbsp;”);
                }
                else if (isDictionary)
                {
                    var IC = (IDictionary)obj;
                    sb.Append(“<table border=’1′>”);
                    foreach (var key in IC.Keys)
                    {
                        sb.Append(“<tr valign=’top’><td>”);
                        //Recursively get the Key to string value
                        sb.Append(ToStringObject(key, DrillLevel – 1, CurrentObjects).HtmlEncode());
                        sb.Append(“</td><td>”);
                        //Recursively get the Value to string value
                        sb.Append(ToStringObject(IC[key], DrillLevel – 1, CurrentObjects));
                        sb.Append(“</tr>”);
                    }
                    sb.Append(“</table>”);
                }
                else if (isEnumerable)
                {
                    int i = 1;
                    foreach (var oo in (IEnumerable)obj)
                    {
                        sb.Append(“<li> #” + i + “</li>”);

                        //Recursively get the Item to string value
                        sb.Append(“<li>” + ToStringObject(oo, DrillLevel – 1) + “</li>”);
                        i++;
                    }
                }
                else
                {
                    if (isPrimitive)
                    {
                        sb.Append(Typecast.ToString(obj).HtmlEncode());
                    }
                    else
                    {
                        if (false && CurrentObjects.Contains(obj))
                        {
                            sb.Append(“~”);
                        }
                        else
                        {
                            CurrentObjects.Add(obj);
                            sb.Append((IgnoreSelf ? Typecast.ToString(obj) : ToStringObject(obj, DrillLevel – 1, CurrentObjects)));
                        }
                    }  
                }
            }
        }
        public override string ToString()
        {
            return ToStringObject(this);
        }

        #region INotifyPropertyChanged Members
        // Declare the PropertyChanged event
        public event PropertyChangedEventHandler PropertyChanged;

        // NotifyPropertyChanged will raise the PropertyChanged event passing the
        // source property that is being updated.
        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }

Categories: ASP.NET