Archive

Archive for the ‘C#’ Category

NHibernate SqlAliasCriterion and Random sorting

December 30th, 2011 No comments

Wrote this custom NHibernate Criterion to be able to add custom SQL snippets with alias support when using criteria.

    public class SqlAliasCriterion : SQLCriterion
    {
        private string sql;
 
        public SqlAliasCriterion(string sql)
            : base(new SqlString(sql), new string[0], new IType[0])
        {
            this.sql = sql;
        }
 
        public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
        {
            string replacedString = Regex.Replace(
                sql,
                @"{([a-zA-Z_]((\.)?[a-zA-Z0-9_])*)}",
                m =>
                {
                    ICriteria critter = criteria.GetCriteriaByAlias(m.Groups[1].Value);
                    if (critter != null)
                    {
                        return criteriaQuery.GetSQLAlias(critter);
                    }
 
                    return m.Groups[0].Value;
                }
            );
 
            return new SqlString(replacedString);
        }
    }

Usage example:

return Session.CreateCriteria<YourClass>("x")
        .Add(new SqlAliasCriterion("{x}.YourField = SomeNativeSQLFunc(foo)"))
        .List<YourClass>();

You can use the same trick to do ordering. (We use this for native MSSQL random ordering)

    public class OrderBySql : Order
    {
        private string sql;
 
        public OrderBySql(string sql, bool ascending)
            : base(String.Empty, ascending)
        {
            this.sql = sql;
        }
 
        public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
        {
            string replacedString = Regex.Replace(
                sql,
                @"{([a-zA-Z_]((\.)?[a-zA-Z0-9_])*)}",
                m =>
                {
                    ICriteria critter = criteria.GetCriteriaByAlias(m.Groups[1].Value);
                    if (critter != null)
                    {
                        return criteriaQuery.GetSQLAlias(critter);
                    }
 
                    return m.Groups[0].Value;
                }
            );
 
            return new SqlString(replacedString + (this.ascending ? " ASC" : " DESC"));
        }
    }

Example with random sorting (MSSQL):

criteria.addOrder(
    new OrderBySql("NEWID()")
);
Categories: C# Tags: , , ,

C# CacheHelper

December 19th, 2011 No comments

Just a simple class I put together for easy cache handling.

public class CacheHelper
{
    private static readonly ILog logger = LogManager.GetLogger(typeof(CacheHelper));
 
    public static T CachedResult<T>(string key, Func<T> valueRetrieval, double timeout = 5)
    {
        T result = (T)HttpContext.Current.Cache[key];
        if (result == null)
        {
            logger.InfoFormat("Cached item with key: {0} not found in Cache, fetching value", key);
 
            result = valueRetrieval.Invoke();
 
            HttpContext.Current.Cache.Insert(key, result, null, DateTime.Now.AddMinutes(timeout), Cache.NoSlidingExpiration);
        }
        else
        {
            logger.DebugFormat("Cached item with key: {0} retrieved from Cache", key);
        }
 
        return result;
    }
}

Usage example:

RssFeed rssFeed = CacheHelper.CachedResult<RssFeed>(url, () => TwitterApplication.GetPublicTimelineFeed(url));
Categories: C# Tags: , ,

Visual Studio, Attach debugger to w3wp process through macro

October 12th, 2011 No comments

Here is a short macro that will attach the debugger to the first w3wp.exe process it can find in the process list. (Script assumes a w3wp.exe process is running. Expect error messages if it doesn’t ;))

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
 
Public Module Famvdploeg
    'Attach the debugger to a w3wp.exe process
    Sub AttachDebugger()
        Try
            'Get your hostname
            Dim hostname As String = System.Net.Dns.GetHostName
            'Load the debugger interface
            Dim debugger As EnvDTE80.Debugger2 = DTE.Debugger
            'Get a local transport, (this is the "Default")
            Dim trans As EnvDTE80.Transport = debugger.Transports.Item("Default")
 
            'Attach to the first w3wp.exe command which we find
            Dim dbgeng(3) As EnvDTE80.Engine
            dbgeng(0) = trans.Engines.Item("T-SQL")
            dbgeng(1) = trans.Engines.Item("T-SQL")
            dbgeng(2) = trans.Engines.Item("Managed")
            Dim process As EnvDTE80.Process2 = debugger.GetProcesses(trans, hostname).Item("w3wp.exe")
            process.Attach2(dbgeng)
        Catch ex As System.Exception
            MsgBox(ex.Message)
        End Try
 
    End Sub
End Module

C# XML to Expando

October 9th, 2011 No comments

Made up this extension method for XDocuments to be able to return an Expando object on which the properties of the XML can be navigated. This is still a little bit rough. I found out there is a ElasticObject that probably works a lot better. But this is just a little ‘proof of concept’.
Note that attributes in the XML are not bound in the Expando object.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using System.Xml.Linq;
 
namespace Famvdploeg.Com
{
    public static class XDocumentExtensions
    {
        public static dynamic ToExpandoObject(this XDocument document)
        {
            return ParseNode(document.Root);
        }
 
        private static dynamic ParseNode(XElement item)
        {
            dynamic expando = new ExpandoObject();
            var props = expando as IDictionary<string, object>;
 
            /* Properties of current node. Single and Lists are created here dynamic */
            IEnumerable<IGrouping<string, XElement>> groupedProperties = item.Elements().Where(element => !element.HasElements).GroupBy(x => x.Name.ToString());
 
            foreach (IGrouping<string, XElement> propertyGroup in groupedProperties)
            {
                int nrElements = propertyGroup.Count();
                if (nrElements == 1)
                {
                    props[propertyGroup.Key.ToValidPropertyName()] = propertyGroup.First().Value;
                }
                else
                {
                    var multipleValues = new List<string>();
 
                    foreach (XElement element in propertyGroup)
                    {
                        multipleValues.Add(element.Value);
                    }
 
                    props[propertyGroup.Key.ToValidPropertyName()] = multipleValues;
                }
            }
 
            /* Children of current node. Single and Lists are created here dynamic */
            IEnumerable<IGrouping<string, XElement>> groupedElements = item.Elements().Where(element => element.HasElements).GroupBy(x => x.Name.ToString());
 
            foreach (IGrouping<string, XElement> elementGroup in groupedElements)
            {
                int nrElements = elementGroup.Count();
                if (nrElements == 1)
                {
                    props[elementGroup.Key.ToValidPropertyName()] = ParseNode(elementGroup.First());
                }
                else
                {
                    var multipleElements = new List<dynamic>();
 
                    foreach (XElement element in elementGroup)
                    {
                        multipleElements.Add(ParseNode(element));
                    }
 
                    props[elementGroup.Key.ToValidPropertyName()] = multipleElements;
                }
            }
 
            return expando;
        }
    }
}

Categories: C# Tags: , , , ,

Removing trailing spaces in Visual Studio

November 30th, 2010 4 comments

Trailing spaces or tabs is something I dislike. Using the combination CTRL+R, CTRL+W you can show the whitespace distribution in VS. But screening the lines one by one is a tedious job. That’s why we are going to use regular expressions. Regular expressions in VS are a bit of an odd duck as the syntax is not nice and Perly.

You can read more about regular expressions in Visual Studio here.

Putting this together we get the following:

Find what: ^{.@}:b+$
Replace with: \1

This will seach those nasty trailing whitespaces and remove them.
{.@} -> Match everything, non-greedy. This is our capturing group.
:b+$ -> Match one or more spaces or tabs before the end of the line.

Optionally:
You can add the following macro to Visual Studio (and bind some keystroke):

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
 
Public Module Famvdploeg
    'Remove trailing whitespace from document
    Sub RemoveTrailingWhitespace()
        DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, "( |\t)+$", vsFindOptions.vsFindOptionsRegularExpression, String.Empty, vsFindTarget.vsFindTargetCurrentDocument, , , )
    End Sub
End Module

Exporting blob images from mssql

October 1st, 2010 No comments

Although you can use the export tool from microsoft. I just wrote a small C# app to do the same thing. Below is the code.

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.IO;
 
namespace ExportImages
{
	public class Program
	{
		static void Main(string[] args)
		{
			Program program = new Program();
			program.ExportImages();
		}
 
		private void ExportImages()
		{
			string connectionString = String.Format("Server=&lt;servername&gt;; Database=&lt;databasename&gt;; Integrated Security=SSPI");
			using (SqlConnection connection =
					new SqlConnection(connectionString))
			{
				try
				{
					connection.Open();
					SqlDataAdapter data = new SqlDataAdapter(
						@"select Id, Thumbnail from Images", connection);
					DataSet ds = new DataSet("images");
					int recordsFound = data.Fill(ds);
					for (int index = 0; index < recordsFound; index++)
					{
						int id = (int) ds.Tables[0].Rows[index]["Id"];
						byte[] imageData = (byte[]) ds.Tables[0].Rows[index]["Thumbnail"];
						int imageSize = imageData.GetUpperBound(0);
						FileStream fs = new FileStream(@"F:\images\" + id + "_thumbnail.jpg", FileMode.OpenOrCreate, FileAccess.Write);
						fs.Write(imageData, 0, imageSize);
						fs.Close();
					}
				}
				catch (SqlException e)
				{
					Console.WriteLine(e.Message);
				}
				finally
				{
					if (connection.State != ConnectionState.Closed)
					{
						connection.Close();
					}
				}
			}
		}
	}
}
Categories: C# Tags:

Deserializing XML twitter feeds.

July 2nd, 2010 No comments

1. Use xsd.exe to extract an xsd file from an xml feed.
Download a private xml feed for example from “http://api.twitter.com/1/statuses/user_timeline.xml” and store it to local disk. Use xsd.exe to generate the xsd.
2. Generate the classes from the xsd file you just generated.

xsd.exe yourxsd.xsd /c

3. Add the generated classes to your C# project.
4. Time for some fetching here is a short example:

// encode the username/password
string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://api.twitter.com/1/statuses/user_timeline.xml");
// set the method to GET
request.Method = "GET";
request.ServicePoint.Expect100Continue = false;
// set the authorisation levels
request.Headers.Add("Authorization", "Basic " + user);
request.ContentType = "application/x-www-form-urlencoded";
 
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
	XmlSerializer serializer = new XmlSerializer(typeof(statuses));
	statuses s = serializer.Deserialize(response.GetResponseStream()) as statuses;
 
	listBox1.Items.Clear();
	foreach (statusesStatus status in s.status)
	{
		listBox1.Items.Add(status.text);
	}
}
Categories: C# Tags: , , , , , , ,