如何将ObservableCollection绑定到sql表?

时间:2014-04-21 23:20:39

标签: c# observablecollection

我想将一个ObservableCollection绑定到一个sql表,我想到的是将事件处理程序添加到集合中并跟踪事件类型以处理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中的Selected Object

我的问题是我是在正确的轨道上,是否已经完成过或者我必须从头开始做?

1 个答案:

答案 0 :(得分:0)

这是我的解决方案

首先我创建了2个简单属性

SqlColumn包含sql列名称,如果是主键和列类型

[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;
            }
        }

    }

只保存sql表名的

的SqlTable
 [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}=@{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}=@{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}=@{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);
    }

}