FluentSQL

This is my stab at a fluent interface for accessing SQL objects, using a minimum of fuss. It is strictly a work in progress, however, I mean to extend it. Somehow I never seem to be able to get away from traditional DALs, there is always a stored proc or ten which need to be called, and I’m tired of writing boilerplate code. This makes the whole thing a little easier.

using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace System.Data
{
	public enum SqlObjectType
	{
		UserDefinedFunctionScalar,
		UserDefinedFunctionTable,
		StoredProcedure
	}
	public abstract class FluentConfiguration 
	{
		private object _configuredObject;

		protected internal virtual object ConfiguredObject
		{
			get
			{
				return _configuredObject;
			}
			set
			{
				_configuredObject = value;
			}
		}
	}
	public abstract class FluentConfiguration<TConfiguredObject> : FluentConfiguration
	{
		protected new TConfiguredObject ConfiguredObject
		{
			get
			{
				return (TConfiguredObject)base.ConfiguredObject;
			}
			set
			{
				base.ConfiguredObject = value;
			}
		}
		public FluentConfiguration(TConfiguredObject configuredObject)
		{
			this.ConfiguredObject = configuredObject;
		}
	}


	public abstract class FluentConfiguration<TConfiguredObject, TParentConfiguration> : FluentConfiguration<TConfiguredObject> where TParentConfiguration : FluentConfiguration
	{
		private FluentConfiguration _parent;
		protected internal virtual FluentConfiguration Parent
		{
			get
			{
				return _parent;
			}
		}
		public FluentConfiguration(TConfiguredObject configuredObject, FluentConfiguration parentConfiguration) : base (configuredObject)
		{
			this._parent = parentConfiguration;
		}
	}

	public class ParameterConfiguration : FluentConfiguration<SqlParameterCollection, CommandConfiguration>
	{
		public ParameterConfiguration(SqlParameterCollection parameters, CommandConfiguration parent) : base(parameters, parent) { }

		public ParameterConfiguration Add(string parameterName, object value)
		{
			this.ConfiguredObject.AddWithValue(parameterName, value);
			return this;
		}

		public CommandConfiguration Finish()
		{
			return (CommandConfiguration)this.Parent;
		}
	}

	public class ConnectionConfiguration : FluentConfiguration<SqlConnection, CommandConfiguration>
	{
		public ConnectionConfiguration(SqlConnection parameters, CommandConfiguration parent) : base(parameters, parent) { }

		public ConnectionConfiguration Conf(Action<SqlConnection> configurationDelegate)
		{
			configurationDelegate(this.ConfiguredObject);
			return this;
		}

		public CommandConfiguration Command()
		{
			return (CommandConfiguration)this.Parent;
		}
	}

	public class CommandConfiguration : FluentConfiguration<SqlCommand>
	{
		public CommandConfiguration(SqlCommand command)
			: base(command)
		{
		}

		public CommandConfiguration Params(Action<SqlParameterCollection> configurationDelegate)
		{
			configurationDelegate(this.ConfiguredObject.Parameters);
			return this;
		}

		public CommandConfiguration QuickAdd(string parameterName, object parameterValue)
		{
			this.Params((p) => p.AddWithValue(parameterName, parameterValue));
			return this;
		}

		public CommandConfiguration Params(IDictionary<string, object>parameterNamesAndValues)
		{
			foreach (string key in parameterNamesAndValues.Keys)
			{
				var value = parameterNamesAndValues[key];
				this.Params((p) => p.AddWithValue(key, value));
			}
			return this;
		}

		public CommandConfiguration Connect(string connectionString)
		{
			Connect((c) => c.ConnectionString = connectionString);
			return this;
		}

		public CommandConfiguration Connect(Action<SqlConnection> configurationDelegate)
		{
			this.ConfiguredObject.Connection = new SqlConnection();
			configurationDelegate(this.ConfiguredObject.Connection);
			return this;
		}


		public ParameterConfiguration Parameters()
		{
			return new ParameterConfiguration(ConfiguredObject.Parameters, this);
		}
		public ConnectionConfiguration Connect()
		{
			return new ConnectionConfiguration(ConfiguredObject.Connection, this);
		}
		public DataSet ExecuteDataSet()
		{
			if(this.ConfiguredObject.Connection == null) return null;
			this.ConfiguredObject.Connection.Open();
			var da = new SqlDataAdapter(ConfiguredObject);
			var ds = new DataSet();
			da.Fill(ds);
			this.ConfiguredObject.Connection.Close();
			this.ConfiguredObject.Connection.Dispose();
			return ds;
		}
	}

	public class FluentSql
	{
		public static CommandConfiguration ConfigureSPCall(string objectName)
		{
			SqlCommand command = new SqlCommand();
			command.CommandType = CommandType.StoredProcedure;
			command.CommandText = objectName;
			CommandConfiguration confObject = new CommandConfiguration(command);
			return confObject;
		}
	}
}

Advertisements

About this entry