Create a Parameter Provider

A parameter provider is a class (typically a model in an MVC environment) that implements the IParameterProvider interface. This is not a required step; you can utilize Database Abstraction without these, by simply providing parameter dictionaries for each call. (In fact, this is the approach taken in the DatabaseAbstractionMembershipProvider and DatabaseAbstractionRoleProvider implementations.) However, if you control your model objects, implementing this interface can make your service code very light, approaching trivial.

The IParameterProvider interface specifies a single method that must be implemented, the Parameters method. Additionally, the Select() methods of data services return an IDataReader; providing a constructor that uses IDataReader will allow seamless integration for your model classes. The following class demonstrates both these in practice.

namespace DocExample.Models
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using DatabaseAbstraction.Interfaces;
    using DatabaseAbstraction.Utils;

    /// <summary>
    /// This class serves as a handy example
    /// </summary>
    public class Example : IParameterProvider
    {
        /// <summary>
        /// The ID of this example
        /// </summary>
        public int ID { get; set; }

        /// <summary>
        /// The first column for this example
        /// </summary>
        public string Column1 { get; set; }

        /// <summary>
        /// The second column in this example
        /// </summary>
        public bool Column2 { get; set; }

        /// <summary>
        /// The third column in this example
        /// </summary>
        public DateTime? Column3 { get; set; }

        /// <summary>
        /// Constructor (empty object)
        /// </summary>
        public Example() { }

        /// <summary>
        /// Constructor (filled object)
        /// </summary>
        /// <param name="reader">
        /// An open data reader, pointing to the row to use
        /// </param>
        public Example(IDataReader reader)
        {
            ID = reader.GetInt32(reader.GetOrdinal("example_id"));
            Column1 = reader.GetString(reader.GetOrdinal("column_1"));
            Column2 = reader.GetBoolean(reader.GetOrdinal("column_2"));
            Column3 = NullUtils.GetDateTimeOrNull(reader, "column_3");
        }

        /// <summary>
        /// Get the properties of this object as a parameter dictionary
        /// </summary>
        /// <returns>
        /// The properties of this object as a parameter dictionary
        /// </returns>
        public IDictionary<string, object> Parameters()
        {
            var parameters = new Dictionary<string, object>();

            parameters.Add("example_id", ID);
            parameters.Add("column_1", Column1);
            parameters.Add("column_2", Column2);
            parameters.Add("column_3", NullUtils.GetNullOrDateTime(Column3));

            return parameters;
        }
    }
}
TIP: This also illustrates a use of the NullUtils class. It contains Get*OrNull() implementations for all data types, that will return null even if the data type is a non-nullable struct (such as int or DateTime). There are also Get*() methods that coalesce null values from the data store into the default value for the struct (ex. null int = 0). Finally, in the Parameters() method, we use one of the GetNullOr*() methods, which return null for Nullable<?> object types. The combination of these three method types should keep you from having to check for DbNull values on any IDataReader accesses.

<<

Last edited May 6, 2012 at 5:51 AM by danielsummers, version 1

Comments

No comments yet.