這裏是我的解決方案
一是我裝箱2個簡單的屬性
SqlColumn保存SQL列名,如果它的的PrimaryKey和列類型
[AttributeUsage(AttributeTargets.Property,Inherited=false)]
public class SqlColumn : Attribute
{
public SqlColumn(string columnName, Type valueType, bool primaryKey)
{
_ColumnName = columnName;
_ValueType = valueType;
_PrimaryKey = primaryKey;
}
private string _ColumnName;
private Type _ValueType;
private bool _PrimaryKey;
public string ColumnName
{
get
{
return this._ColumnName;
}
set
{
_ColumnName = value;
}
}
public Type ValueType
{
get
{
return this._ValueType;
}
set
{
_ValueType = value;
}
}
public bool PrimaryKey
{
get
{
return this._PrimaryKey;
}
set
{
_PrimaryKey = value;
}
}
}
SQLTABLE剛剛保存SQL表名
[AttributeUsage(AttributeTargets.Class,AllowMultiple=false,Inherited=false)]
public class SqlTable : Attribute
{
public SqlTable(string TableName)
{
this._TableName = TableName;
}
protected String _TableName;
public String TableName
{
get
{
return this._TableName;
}
}
}
和一個sql命令生成器或者我用來在集合中創建相關的sql命令更改事件處理程序和屬性更改事件處理程序
public static class SqlGenerator
{
public static SqlCommand GenerateSelectCommand<T>()
{
string TableName = GetTableName<T>();
PropertyInfo[] props = GetPropertyInfos<T>();
//StringBuilder sbWhere = new StringBuilder(" WHERE ");
StringBuilder sbColumns = new StringBuilder(" ");
var cmd = new SqlCommand();
foreach (var prop in props)
{
sbColumns.Append(prop.Name);
}
cmd.CommandText =
"SELECT " +
sbColumns.ToString().TrimEnd(',') +
" FROM " + TableName;
return cmd;
}
public static SqlCommand GenerateInsertCommand<T>(object Obj)
{
string TableName = GetTableName<T>();
PropertyInfo[] props = GetPropertyInfos<T>();
var cmd = new SqlCommand();
StringBuilder sbColumns = new StringBuilder(" ");
StringBuilder sbValues = new StringBuilder(" ");
foreach(var prop in props)
{
var sqlColumnAttr = (SqlColumn)prop.GetCustomAttribute(typeof(SqlColumn), false);
var colValue = prop.GetValue(Obj);
if(!sqlColumnAttr.PrimaryKey && colValue!=null)
{
sbColumns.AppendFormat("{0},",sqlColumnAttr.ColumnName);
sbValues.AppendFormat("@{0},", sqlColumnAttr.ColumnName);
var param = new SqlParameter("@" + sqlColumnAttr.ColumnName, colValue);
param.DbType = (DbType)Enum.Parse(typeof(DbType), sqlColumnAttr.ValueType.Name);
cmd.Parameters.Add(param);
}
}
cmd.CommandText = "INSERT INTO " + TableName +"("+ sbColumns.ToString().TrimEnd(',') +") VALUES(" + sbValues.ToString().TrimEnd(',') + ");SELECT SCOPE_IDENTITY();";
return cmd;
}
public static SqlCommand GenerateUpdateCommand<T>(object Obj,IEnumerable<string> PropertyNamesThatChanged)
{
string TableName = GetTableName<T>();
PropertyInfo[] props = GetPropertyInfos<T>().Where(pinfo=>!PropertyNamesThatChanged.Contains(pinfo.Name)).ToArray();
var cmd = new SqlCommand();
StringBuilder sbValues = new StringBuilder(" ");
StringBuilder sbWhere = new StringBuilder(" WHERE ");
foreach (var prop in props)
{
var sqlColumnAttr = (SqlColumn)prop.GetCustomAttribute(typeof(SqlColumn), false);
var colValue = prop.GetValue(Obj);
if (!sqlColumnAttr.PrimaryKey && colValue != null)
{
sbValues.AppendFormat("{0}[email protected]{0},", sqlColumnAttr.ColumnName);
var param = new SqlParameter("@" + sqlColumnAttr.ColumnName, colValue);
param.DbType = (DbType)Enum.Parse(typeof(DbType), sqlColumnAttr.ValueType.Name);
cmd.Parameters.Add(param);
}
else if(sqlColumnAttr.PrimaryKey)
{
sbWhere.AppendFormat("{0}[email protected]{0}", sqlColumnAttr.ColumnName);
var param = new SqlParameter("@" + sqlColumnAttr.ColumnName, colValue);
param.DbType = (DbType)Enum.Parse(typeof(DbType), sqlColumnAttr.ValueType.Name);
cmd.Parameters.Add(param);
}
}
cmd.CommandText = "UPDATE " + TableName + sbValues.ToString().TrimEnd(',') + sbWhere.ToString();
return cmd;
}
public static SqlCommand GenerateDeleteCommand<T>(object Obj)
{
string TableName = GetTableName<T>();
PropertyInfo[] props = GetPropertyInfos<T>();
StringBuilder sbWhere = new StringBuilder(" WHERE ");
var cmd = new SqlCommand();
foreach (var prop in props)
{
var sqlColumnAttr = (SqlColumn)prop.GetCustomAttribute(typeof(SqlColumn), false);
if(sqlColumnAttr.PrimaryKey)
{
var colValue = prop.GetValue(Obj);
sbWhere.AppendFormat("{0}[email protected]{0}", sqlColumnAttr.ColumnName);
var param = new SqlParameter("@" + sqlColumnAttr.ColumnName, colValue);
param.DbType = (DbType)Enum.Parse(typeof(DbType), sqlColumnAttr.ValueType.Name);
cmd.Parameters.Add(param);
}
}
cmd.CommandText = "DELETE FROM " + TableName + sbWhere.ToString();
return cmd;
}
public static string GetTableName<T>()
{
return typeof(T).GetAttributeValue((SqlTable sqlTable)=> sqlTable.TableName);
}
public static PropertyInfo[] GetPropertyInfos<T>()
{
return typeof(T).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(SqlColumn))).ToArray();
}
public static TValue GetAttributeValue<TAttribute, TValue>(
this Type type,
Func<TAttribute, TValue> valueSelector)
where TAttribute : Attribute
{
var att = type.GetCustomAttributes(
typeof(TAttribute), true
).FirstOrDefault() as TAttribute;
if (att != null)
{
return valueSelector(att);
}
return default(TValue);
}
}
沒有冒犯但我認爲您的概念有嚴重的缺陷。重置收藏或更換物品會發生什麼? – Crono
@Crono我可以處理那些收集改變的處理程序,但它不會發生在我的情況 – FPGA