Och som alla andra gånger så skapar vi ett DataIdentifierInformation objekt som kan hålla informationen om vår identifier
[Serializable]
internal class DataIdentifierInformation
{
#region -- Declaration
private IdentifierTypeEnum _IdentifierType;
private IdentifierSaveActionEnum _IdentifierSaveAction;
private string _DataFieldName;
private string _ClassName;
private Type _Type;
private object _Value;
#endregion
#region -- Properties
public IdentifierTypeEnum IdentifierType
{
get { return _IdentifierType; }
}
public IdentifierSaveActionEnum IdentifierSaveAction
{
get { return _IdentifierSaveAction; }
}
public string DataFieldName
{
get { return _DataFieldName; }
}
public string ClassFieldName
{
get { return _ClassName; }
}
public Type Type
{
get { return _Type; }
}
public object Value
{
get { return _Value; }
}
#endregion
#region -- Constructor
public DataIdentifierInformation() { }
public DataIdentifierInformation(string dataFieldName, string className, IdentifierTypeEnum identifierType, IdentifierSaveActionEnum identifierSaveAction, Type type)
{
_DataFieldName = dataFieldName;
_ClassName = className;
_IdentifierType = identifierType;
_IdentifierSaveAction = identifierSaveAction;
_Type = type;
if (_IdentifierType == IdentifierTypeEnum.UniqueIdentifier)
_Value = new Identifier(Guid.NewGuid());
}
public DataIdentifierInformation(string dataFieldName, string className, IdentifierTypeEnum identifierType, IdentifierSaveActionEnum identifierSaveAction, Type type, object value)
{
_DataFieldName = dataFieldName;
_ClassName = className;
_IdentifierType = identifierType;
_IdentifierSaveAction = identifierSaveAction;
_Type = type;
_Value = value;
}
#endregion
}
Och så metoden som plockar fram denna information från vår Userklass.
private DataIdentifierInformation CreateDataIdentifierInformation<ItemType>(ItemType itemType, Identifier identifier)
{
//-- Get all fieldInfors for the ItemType
FieldInfo[] fieldInfos = itemType.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (fieldInfos == null || fieldInfos.Length == 0)
throw new Exception();
//-- Create object
DataIdentifierInformation dataIdentifierInformation = null;
//-- Loop through all fieldinfo and get DataFieldInfo from them
for (int i = 0; i < fieldInfos.Length; i++)
{
//-- Check if this field has an DataFieldAttribute on it
DataIdentifierAttribute[] dataIdentifierAttribute = (DataIdentifierAttribute[])fieldInfos[i].GetCustomAttributes(typeof(DataIdentifierAttribute), true);
if (dataIdentifierAttribute == null || dataIdentifierAttribute.Length == 0)
continue;
//-- Get the datafield attribute for this field
DataFieldAttribute[] dataFieldAttributes = (DataFieldAttribute[])fieldInfos[i].GetCustomAttributes(typeof(DataFieldAttribute), true);
if (dataFieldAttributes == null || dataFieldAttributes.Length == 0)
throw new Exception("No DataFieldAttirbute defined for memberfield that has DataIdentifierAttribute defined");
if (dataFieldAttributes.Length > 1)
throw new Exception("Multiple DataFieldAttirbute defined for memeberfield that has DataIdentifierAttribute");
//-- Create DataIdentifierInformation
//-- When we have supplied an identifier that we want to use
if(identifier != null)
dataIdentifierInformation = new DataIdentifierInformation(
dataFieldAttributes[0].FieldName
, fieldInfos[i].Name
, dataIdentifierAttribute[0].IdentifierType
, identifier.IdentifierSaveAction
, identifier.Type
, identifier);
//-- No supplied identifier, but the itemType has an identifier that has a value
else if (fieldInfos[i].GetValue(itemType) != null)
dataIdentifierInformation = new DataIdentifierInformation(
dataFieldAttributes[0].FieldName
, fieldInfos[i].Name
, dataIdentifierAttribute[0].IdentifierType
, ((Identifier)fieldInfos[i].GetValue(itemType)).IdentifierSaveAction
, ((Identifier)fieldInfos[i].GetValue(itemType)).Type
, fieldInfos[i].GetValue(itemType));
//-- No supplied identifier and the itemtype has no value in it's identifier
else
{
dataIdentifierInformation = new DataIdentifierInformation(
dataFieldAttributes[0].FieldName
, fieldInfos[i].Name
, dataIdentifierAttribute[0].IdentifierType
, IdentifierSaveActionEnum.Insert
, fieldInfos[i].FieldType);
//-- if the identifier is uniqueidentifier we need to set the identifiers value
if (dataIdentifierInformation.IdentifierType == IdentifierTypeEnum.UniqueIdentifier)
SetIdentifier<ItemType>(itemType, dataIdentifierInformation.Value);
}
break;
}
return dataIdentifierInformation;
}
Nu kan vi alltså skapa dataIdentifierInformation från vår klass som vi kan använda när vi vill hämta ut bara ett objekt från databasen...
Så vi skapar ytterligare en LoadMetod
public ItemType Load<ItemType>(Identifier identifier)
{
//-- declare variables
IDbCommand command = null;
DataTable dataTable = null;
try
{
//-- Create information objects
.
.
.
DataIdentifierInformation dataIdentifierInformation = CreateDataIdentifierInformation<ItemType>(Activator.CreateInstance<ItemType>(), identifier);
//-- Create Command
command = CreateSelectCommand(dataFieldInformationList, dataSourceInformation, dataIdentifierInformation);
.
.
.
//-- Convert dataTable to TSLis<ItemType>
List<ItemType> itemTypeList = MapDataTableToCollection<ItemType>(dataTable, dataFieldInformationList);
//-- return itemtypes
if (itemTypeList == null || itemTypeList.Count == 0)
return default(ItemType);
else
return itemTypeList[0];
}
finally
{
if (dataTable != null)
dataTable.Dispose();
if (command != null)
command.Dispose();
}
}
Här har vi nu ytterligare en ny CreateSelectCommand Method som vi måste hantera och vi har dessutom lagt till en sista kodnutt som kommer att returnera ett objekt eller default värdet för detta objekt (som nästa alltid kommer att vara null).
Då tittar vi lite på vår CreateSelectCommand(). Vad vi kan göra här är att antigen skapa en ny överlagrad method, eller så utökar vi bara metoden som vi hade innan med whereStatmententet och så skickar vi med NULL som whereStatement så här.
private IDbCommand CreateSelectCommand(List<DataFieldInformation> dataFieldInformationList, DataSourceInformation dataSourceInformation, DataIdentifierInformation dataIdentifierInformation, string whereStatement)
{
//-- Create commandobject
StringBuilder sb = new StringBuilder()
string tmpWhereStatement = string.Empty;
IDbCommand command = CreateSqlCommand();
command.CommandText = SELECT(dataFieldInformationList, dataSourceInformation);
//-- Check if this selectcommand shall have a where statement based on identifier field...
if (dataIdentifierInformation != null)
{
//-- Adds the where sqlstatement to the command text
tmpWhereStatement = WHERE(dataIdentifierInformation);
//-- Create parameterlist for dataIdentifierInformation
foreach (IDataParameter parameter in CreateParameterList(dataIdentifierInformation))
command.Parameters.Add(parameter);
}
//-- Check for where statement
if(!string.IsNullOrEmpty(tmpWhereStatement)
{
if(!string.IsNullOrEmpty(whereStatement))
sb.Append(tmpWhereStatement).Append(" AND ").Append(whereStatement);
else
sb.Append(tmpWhereStatement);
}else
if(!string.IsNullOrEmpty(whereStatement))
sb.Append(" WHERE ").Append(whereStatement);
//-- returnerar command object.
command.CommandText = sb.ToString();
return command;
}
Då fick vi helt plötsligt 2 nya metoder som vi inte har sett innan. WHERE() och CreateParameterList och de ser ut så här.
private string WHERE(DataIdentifierInformation dataIdentifierInformation)
{
StringBuilder sb = new StringBuilder();
sb.Append(" WHERE ");
sb.Append("[").Append(dataIdentifierInformation.DataFieldName).Append("] = ");
sb.Append("@_").Append(dataIdentifierInformation.ClassFieldName);
//-- return the WHERE statement
return sb.ToString();
}
- M