<#@ Template Language="C#" #>
<#@ Assembly Name="System.dll" #>
<#@ Assembly Name="System.Data.dll" #>
<#@ Assembly Name="System.Xml.dll" #>
<#@ Assembly Name="Howest.Guidance.DataAccess.dll" #>
<#@ Assembly Name="Howest.SchemaDiscovery.Common.dll" #>
<#@ Import Namespace="System" #>
<#@ Import Namespace="System.Data" #>
<#@ Import Namespace="System.Xml.Serialization" #>
<#@ Import Namespace="Howest.Guidance.DataAccess.CodeGeneration.ObjectModel" #>
<#@ Import Namespace="Howest.Guidance.DataAccess.CodeGeneration.ObjectModel.Mappings" #>
<#@ Import Namespace="Howest.Guidance.DataAccess.CodeGeneration.ObjectModel.Mappings.Enums" #>
<#@ Import Namespace="Howest.Guidance.DataAccess.CodeGeneration.ObjectModel.NamingConventions" #>
<#@ Import Namespace="Howest.Guidance.DataAccess.CodeGeneration.ObjectModel.Helpers" #>
<#@ Import Namespace="Howest.SchemaDiscovery.DbObjects" #>
<#@ Property Processor="PropertyProcessor" Name="Entities"#>
<#@ Property Processor="PropertyProcessor" Name="DataEntityClassNamespace" #>
<#@ Property Processor="PropertyProcessor" Name="DataAccessClassNamespace" #>
<#@ include file="Templates\T4\Common\NamingHelper.t4" #>
<#@ include file="Templates\T4\Common\DataAccessorHelper.t4" #>

<#
foreach(Entity entity in Entities) 
{#>
// begin "<#= entity.Name #>DataAccessor.cs"

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;

using <#= this.DataEntityClassNamespace #>;

namespace <#= DataAccessClassNamespace#>
{
    public partial class <#= entity.Name #>DataAccessor : DbDataAccessor
    {
		<#
			foreach(EntitySqlStatementMapping mapping in entity.SqlStatementMappings)
			{
				if(mapping.MappingType == SqlStatementMappingType.Output)
				{
					foreach(SqlStatement stat in mapping.Statements)
					{
						if(stat.OperationType == OperationType.GetOne)
						{
		#>
		public <#= entity.Name #> <#= stat.MethodName #>(<#= GetMethodParameterList(stat)#>)
		{
			string sql = "<#= stat.Sql #>";
			DbParameter[] parameters = new DbParameter[] {
            <#
				foreach(Parameter par in stat.Parameters)
				{
			#>
                Database.CreateParameter(<#= CreateParameterValues(par)#>),
            <#
				}
			#>
            };
			DbCommand cmd = Database.CreateSqlCommand(sql, parameters);
			DbDataReader reader = Database.ExecuteReader(cmd);
            return ReadSingle<#= entity.Name #>(reader);
		}
		<#
						}
						else
						{
		#>
		public List<<#= entity.Name #>> <#= stat.MethodName #>(<#= GetMethodParameterList(stat)#>)
		{
			string sql = "<#= stat.Sql #>";
			DbParameter[] parameters = new DbParameter[] {
			<#
				foreach(Parameter par in stat.Parameters)
				{
			#>
                Database.CreateParameter(<#= CreateParameterValues(par)#>),
            <#
				}
			#>
            };
			DbCommand cmd = Database.CreateSqlCommand(sql, parameters);
			DbDataReader reader = Database.ExecuteReader(cmd);
            return ReadMultiple<#= entity.Name #>(reader);
		}
		<#
						}
					}
		#>
		
		#region Private Helper Methods

        private <#= entity.Name #> Fill<#= entity.Name #>ObjectData(DbDataReader reader)
        {
            object data = null;
            <#= entity.Name #> <#= GetVariableName(entity.Name) #> = new <#= entity.Name #>();
            <#
				foreach(PropertyParameterMapping ppMap in mapping.ParameterMappings)
				{
					Property prop = GetPropertyByName(entity, ppMap.Property);
					if(ppMap.ParameterInstance.DbDataType.AllowDbNull)
					{
            #>
            data = reader["<#= ppMap.Parameter#>"];
            <#= GetVariableName(entity.Name) #>.<#= ppMap.Property #> = data == DBNull.Value ? default(<#= prop.Type.ToString()#>) : (<#= prop.Type.ToString()#>)data;
            <#
					}
					else
					{
			#>
            <#= GetVariableName(entity.Name) #>.<#= ppMap.Property #> = (<#= prop.Type.ToString()#>)reader["<#= ppMap.Parameter#>"];
            <#
					}
				}
            #>
            return <#= GetVariableName(entity.Name) #>;
        }

        private <#= entity.Name #> ReadSingle<#= entity.Name #>(DbDataReader reader)
        {
            try
            {
                if (reader.Read())
                {
                    return Fill<#= entity.Name #>ObjectData(reader);
                }
                return null;
            }
            finally
            {
                reader.Close();
            }
        }

        private List<<#= entity.Name #>> ReadMultiple<#= entity.Name #>(DbDataReader reader)
        {
            try
            {
                List<<#= entity.Name #>> list = new List<<#= entity.Name #>>();
                while (reader.Read())
                {
                    list.Add(Fill<#= entity.Name #>ObjectData(reader));
                }
                return list;
            }
            finally
            {
                reader.Close();
            }
        }

        #endregion
		
		<#
				}
				else
				{
					SqlStatement statement = mapping.Statements[0];
		#>
		public void <#= statement.MethodName #>(<#= entity.Name #> <#= GetVariableName(entity.Name) #>)
		{
			string sql = "<#= statement.Sql #>";
			DbParameter[] parameters = new DbParameter[] {
			<#
				foreach(PropertyParameterMapping ppMap in mapping.ParameterMappings)
				{
			#>
				Database.CreateParameter(<#= CreateParameterValues(entity, ppMap.Property, ppMap.ParameterInstance)#>),
			<#
				}
			#>
			};
			DbCommand cmd = Database.CreateSqlCommand(sql, parameters);
			Database.ExecuteNonQuery(cmd);
		}
		<#
				}
			}
		#>
    }
}
// end "<#= entity.Name #>DataAccessor.cs"
<#
}// foreach(Entity entity in Entities) 
#>