zoukankan      html  css  js  c++  java
  • DataTable:数据库到程序的桥梁

      DataTable:是一个临时保存数据的网格虚拟表(表示内存中数据的一个表。)。DataTable是ADO dot net 库中的核心对象,它无须代码就可以简单的绑定数据库,它具有微软风格的用户界面。其他使用DataTable的对象包括DataSetDataView

      我个人对DataTable的理解就是数据库到程序的桥梁。执行sql语句之后把获取的表单数据转化成DataTable格式放入内存中,应用到程序的各个组件。也可以进行DataTable与泛型之间的转化,提升了泛型灵活性。

      DataSet:可以理解成若干DataTable的集合,DataSet在内存里面维护一个表集合包括表间关系。对于.NET Framework 2.0之前的版本,DataSet在ADO.NET中拥有至关重要的作用,但在其后的版本中,由于DataTable类的完备(例如与XML相关的几个方法以及Merge方法),其作用稍有削弱,甚至于有些情况下你去初始化一个DataSet对象本身就是多余的。

      DataView:与数据库中的视图在概念上是类似的。DataView本身并不真正包含数据行,而只是包含指向源DataTable中数据行的引用,这一点你可以通过object.ReferenceEquals()方法来验证。

      既然DataTable是数据库到程序的桥梁。那么DataTable的改变当然可以保存到数据库,也可以转化为泛型,返回到交互页面。

    一、DataTable更新到数据库

      1.1 直接使用SQL命令

      在.NET中,最常见的是拼接SQL字符串,使用Command对象来执行此命令以达到操作Database的目的,例如,

    string sql = "update table1 set fvalue=" + this.textBox1.Text + " where fname='x'";
    SqlCommand cmd = new SqlCommand(sql,conn);
    cmd.ExecuteNonQuery();

    这是一种最直接浅显的方式,

      1.2 使用DataAdapter.Update()

      另外一种方式,是使用DataAdapter.Update()方法,这并不是说我们不需要SQL语句了,只是SQL语句拼接的工作已经交给了DataAdapter(实际上是交给了CommandBuilder)来完成(以参数的形式),例如,  

    string c = "select fname,fvalue from table1";
    SqlCommand cmd = new SqlCommand(c,conn);
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    SqlCommandBuilder scb = new SqlCommandBuilder(da); //(1)
    DataTable dt = new DataTable();
    da.Fill(dt);
    dt.Rows[0].Delete();//(2)
    da.Update(dt);

      在这里,你看不到SQL语句,因为在你初始化SqlCommandBuilder的过程中,将自动根据表结构(基于你的Select语句)构造insert,update,delete语句。对于上面的代码,你可以获得SQL语句内容,

    DELETE FROM [table1] WHERE (([fname] = @p1) AND ((@p2 = 1 AND [fvalue] IS NULL) OR ([fvalue] = @p3)))

    而执行时候,会传入相应的参数值,

    exec sp_executesql N'DELETE FROM [table1] WHERE (([fname] = @p1) AND ((@p2 = 1 AND [fvalue] IS NULL) OR ([fvalue] = @p3)))',N'@p1 varchar(1),@p2 int,@p3 int',@p1='a',@p2=0,@p3=100
    或xec sp_executesql N'DELETE FROM [table1] WHERE (([fname] = @p1) AND ((@p2 = 1 AND [fvalue] IS NULL) OR ([fvalue] = @p3)))',N'@p1 varchar(1),@p2 int,@p3 int',@p1='b',@p2=1,@p3=NULL

    由于表中只有两个列,列fname为主键列,fvalue列可空,至于为什么会出现三个参数,看看上面的SQL你就会明白了。

    二、DataTable与List<T>相互转化

    2.1 List<T>转换为datatable

    public static DataTable ToDataTable(IList list)
            {
                DataTable result = new DataTable();
                if (list.Count > 0)
                {
                    PropertyInfo[] propertys = list[0].GetType().GetProperties();
                    foreach (PropertyInfo pi in propertys)
                    {
                        result.Columns.Add(pi.Name, pi.PropertyType);
                    }
                    for (int i = 0; i < list.Count; i++)
                    {
                        ArrayList tempList = new ArrayList();
                        foreach (PropertyInfo pi in propertys)
                        {
                            object obj = pi.GetValue(list[i], null);
                            tempList.Add(obj);
                        }
                        object[] array = tempList.ToArray();
                        result.LoadDataRow(array, true);
                    }
                }
                return result;
            }
    View Code

    2.2datatable转List<T>

    public static List<T> ConvertToEx<T>(DataTable dt) where T : new()
            {
                if (dt == null) return null;
                if (dt.Rows.Count <= 0) return null;
     
                List<T> list = new List<T>();
                Type type = typeof(T);
                PropertyInfo[] propertyInfos = type.GetProperties();  //获取泛型的属性
                List<DataColumn> listColumns = dt.Columns.Cast<DataColumn>().ToList();  //获取数据集的表头,以便于匹配
                T t;
                foreach (DataRow dr in dt.Rows)   
                {
                    t = new T();
                    foreach (PropertyInfo propertyInfo in propertyInfos)
                    {
                        try
                        {
                            DataColumn dColumn = listColumns.Find(name => name.ToString().ToUpper() == propertyInfo.Name.ToUpper());  //查看是否存在对应的列名
                            if (dColumn != null)
                                propertyInfo.SetValue(t, dr[propertyInfo.Name], null);  //赋值
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(ex.Message);
                        }
                    }
                    list.Add(t);
                }
                return list;
            }
    View Code

    最后介绍一个小知识点,因为操作数据表,肯定离不开数据类型,C#中与类型Type有关的3个语句:

    1、typeof

    typeof是个运算符,typeof(类型)。例如typeof(bool)、typeof(int)、typeof(System.Windows.Forms.TextBox)

    2、Type.GetType(类型名)。这个类型名是string型,加引号的。

    3、Object.GetType()。Object类的成员,c#的类对象都有此方法。

    上面3个都返回System.Type。

     

  • 相关阅读:
    JS 、JQ 获取宽高总结 & JS中getBoundingClientRect的作用及兼容方案
    JS与JQ 获取页面元素值的方法和差异对比
    ES6
    移动端:active伪类无效的解决方法
    JavaScript中valueOf函数与toString方法
    Reverse Words in a String -- LeetCode
    Count Primes -- LeetCodes (primality test)
    Maximum Size Subarray Sum Equals k -- LeetCode
    Subsets II -- LeetCode
    Maximum Product of Word Lengths -- LeetCode
  • 原文地址:https://www.cnblogs.com/qixinbo/p/7094473.html
Copyright © 2011-2022 走看看