2014-04-21 54 views
0

我想要一個ObservableCollection綁定到一個SQL表,我想添加事件處理的收集和跟蹤事件類型來處理SQL刪除和插入操作,如如何將ObservableCollection綁定到sql表?

someobservablecollection.CollectionChanged += (s, e) => 
       { 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) 
        { 
         //Generate sql Insert command for e.NewItems using reflection 
        } 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove) 
        { 
         //Generate sql Delete command for e.OldItems 
        } 
       }; 

和更新我將不得不添加事件處理程序到我的ViewModel中的選定對象

我的問題是我在正確的軌道上,它之前已經完成,還是我必須從頭開始?

回答

0

這裏是我的解決方案

一是我裝箱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); 
    } 

} 
+0

沒有冒犯但我認爲您的概念有嚴重的缺陷。重置收藏或更換物品會發生什麼? – Crono

+0

@Crono我可以處理那些收集改變的處理程序,但它不會發生在我的情況 – FPGA

相關問題