C# 2

简介: ADO.NET 和 LINQ using DataSet 1.用DataReader读取数据     读取SQL数据库:     ......     using System.

ADO.NET 和 LINQ using DataSet
1.用DataReader读取数据
    读取SQL数据库:

    ......

    using System.Data;        //使用ADO.NET名称空间

    using System.Data.SqlClient;    //使用SQL Server 数据提供者名称空间

    ......
    SqlConnection thisConnection = new SqlConnection(@".......数据库连接字符串.......");    //初始化连接对象,连接字符串因数据库连接而异
    thisConnection.Open();    //打开连接

    SqlCommand thisCommand = thisConnection.CreateCommand();    //建立命令对象,并初始化
    thisCommand.CommandText = "SELECT CustomerIDs, CompanyName from Customers";

    SqlDataReader thisReader = thisCommand.ExecuteReader();    //创建DataReader对象,并执行读取命令
    
    while(thisReader.Read())    //判断是否有读到数据
    {
        Console.WriteLine("/t{0}/t{1}", thisReader["CustomerID"],thisReader["CompanyName"]);

    }

    thisReader.Close();    //关闭DataReader对象

    thisConnection.Close();    //关闭连接
    *****************************************
    读取Access数据库:
     ......
    using System.Data;    //使用ADO.NET名称空间

    using System.Data.OleDb;    //使用OLE DB .NET的名称空间

    ......

    OleDbConnection thisConnection = new OleDbConnection(@"......数据库连接字符串.......");

    thisConnection.Open();

 

    OleDbCommand thisCommand = thisConnection.CreateCommand();

    thisCommand.CommandText = "SELECT CustomerID, CompanyName FROM Customers";


    OleDbDataReader thisReader = thisCommand.ExecteReader();

 

    while(thisReader.Read())

    {
        Console.WriteLine("/t{0}/t{1}",thisReader["CustomerID"],thisReader["CompanyName"]);

    }

    thisReader.Close();

    thisConnection.Close(); 

________________
2.用DataSet读取数据
    .......

    using System.Data;

    using System.Data.SqlClient;

    .......

    SqlConnection thisConnection = new SqlConnection(@"....数据库连接字符串....");

 

    SqlDataAdapter thisAdapter = new SqlDataAdapter("SELECT CustomerID, ContactName FROM Customers", thisConnection); //初始化DataAdapter对象


    DataSet thisDataSet = new DataSet();


    thisAdapter.Fill(thisDataSet, "Customers");    //填充DataSet对象,第一个参数是要填充的DataSet对象,第二个参数是DataSet所包含的表的名称。


    foreach(DataRow theRow in thisDataSet.Table["Customers"].Rows)

    {
        Console.WriteLine(theRow["Customers"] +"/t"+theRow["ContactName"]);

    }

    thisConnection.Close();

       
    DataSet的属性:

     DataSet包含一组DataTable对象,DataTable对象有一些子对象DataRow 和 DataColumn,表示行和列。

        
        Tables属性:

        它是DataSet中所有DataTable对象的集合;
        类型是DataTableCollection

        有两种方式访问每个DataTable:   

            1)按表名访问,如:thisDataSet.Tables["Customers"]指定DataTable对象Customers;

            2)按索引访问:如:thisDataSet.Tables[0]指DataSet中第一个DataTable。

 

        DataTable的Rows属性:

        它是DataRow对象的集合。

        类型是DataRowCollection,是一个有序列表,按行号排序。

        myDataSet.Tables["Customers"].Rows[n]


        访问列:

        DataRow没有Columns属性。但可以按列名访问:

        thisDataSet.Tables["Customers"].Rows[n]["CompanyName"],其中CompanyName就是列名。

        DataRow对象有个索引属性,可以按名称 和 列号访问个列,如:theRow["CustomerID"]访问DataRow对象theRow的CustomerID列。

 

    DataAdapter不改变数据库连接的状态。如果工作开始前连接时打开的,那么结束后也是打开的;如果是关闭的,结束后也是关闭的。
    所有,没有连接没有明确的打开和关闭连接。

________________
3. 更新数据库
    数据库的 修改、插入、删除的步骤:

    1)填充DataSet;

    2)修改DataSet数据;

    3)把DataSet数据返回到数据库。


    修改行:
    例:

         SqlConnection thisConnection = new SqlConnection(@".........ConnectString............");  

         SqlAdapter thisAdapter = new SqlAdapter("SELECT CustomerID, CompanyName FROM Customers", thisConnection);

         SqlCommandBuilder thisBuilder = new SqlCommandBuilder(thisAdapter);    //SqlCommandBuilder创建SQL命令,并与thisAdapter关联

         thisAdapter.Fill(thisDataSet, "Customers");

         ......

         thisDataSet.Tables["Customers"].Rows[9]["CompanyName"] = "Acme, Inc.";    //修改DataSet数据
         thisAdapter.Update(thisDataSet, "Customers");    //更新数据库

         thisConnection.Close();


        SqlCommandBuilder生成SQL命令,包括增、删、改。SqlAdapter.Update()执行时,根据具体情况(增删改数据)执行相应的操作。

        DataRow类的RowState属性会追踪 行有什么变动,做为Update()执行的依据。

 

    添加行:

    例:

       .......

       thisAdapter.Fill(thisDataSet, "Customers"); //之前的代码与上例一样

       .......
        //在DataSet中加入新行
       DataRow thisRow = thisDataSet.Tables["Customers"].NewRow();    //用Tables["Customers"]的DataRow结构,初始化DataRow。

       thisRow["CustomerID"] = "ZZ099";

       thisRow["CompanyName"] = "Ares Lab";

       thisDataSet.Tables["Customers"].Rows.Add(thisRow);    //将新建的DataRow加入到DataSet中

       thisAdapter.Update(thisDataSet, "Customers");

       thisConnection.Close();

 

    删除行:

    先要查找行,然后删除。

    例:

        ......Fill DataSet & SqlCommandBuild ......

 

        DataColume[] keys = new DataColumn[1];    //创建DataColumn数组,因为键可以由多列组成

        keys[0] = thisDataSet.Tables["Customers"].Columns["CustomerID"];    //为键数组赋值

        thisDataSet.Tables["Customer"].PrimaryKey = keys;    //设置主键,查找行时,通过主键查找

 

        DataRow findRow = thisDataSet.Tables["Customers"].Rows.Find("ZZ009"); //查找行

 

        if(finRow != null)

            findRow.Delete();  //在DataSet中删除行。 Delete()会标记RowState属性,并不执行删除操作。
                                     //当希望从DataSet中删除行,而不是数据库中删除时,用Remove()方法。
        thisAdapter.Update(thisDataSet, "Customers");        
        thisConnection.Close();


        设置主键的另一种方式:

        直接从数据库中加载主键,通过设置DataAdapter的MissingSchemaAction属性。

        thisAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; //这行,通过隐式初始化DataTable的PrimaryKey属性,完成主键的设置。

        thisAdapter.Fill(thisDataSet, "Customers");

       
________________
4. 在DataSet中访问多个表
    DataSet的DataRelation对象,可以跟踪多个表之间的关系。
    DataRelation对象用于描述多个DataTable对象之间的关系。DataRelation对象的集合包含在Relations属性中。

    要创建DataRelation对象,可以用Relation的Add()方法。


    例:

        .....

        using System.Data;

        using System.Data.SqlClient;

 

        .......// 前面的代码省略了

        custAdapter.Fill(thisDataSet, "Customers");    //把Orders &Customer表填充到DataSet中

        orderAdapter.Fill(thisDataSet, "Orders"); 


        DataRelation custOrderRel = thisDataSet.Relations.Add("CustOrders",    //第一参数:关系命名
                          thisDataSet.Tables["Customers"].Columns["CustomerID"],    //第二参数:父表的关联字段
                          thisDataSet.Tables["Orders"].Columns["CustomerID"]);    //第三参数:子表的关联字段

 

        foreach(DataRow custRow in thisDataSet.Tables["Customers"].Rows)

        {
            Console.WriteLine("Customer ID: " + custRow["CustomerID"]);

 

            foreach(DataRow orderRow in custRow.GetChildRows(cusrOrderRel)) //custRow是父表中的一行,由GetChildRows方法依据custOrderRel关系,
            {                                                                                          //在子表中查找的相关行。   
                Console.WriteLine(" Order ID: " + orderRow["OrderID"]); 
            }

        }

 

        使用GetParentRow()获取与此关联的父对象。

________________
5. ADO.NET DataSet中的XML支持
    ADO.NET中XML支持主要集中于DataSet对象,因为XML主要关注的是关系 和 分层的结构化数据。

    从DataSet中写入XML:
        1)构造一个DataSet;
        2)DataAdapter对象的Fill()方法加载数据;

        3)DataSet上调用WriteXml(),比如:thisDataSet.WriteXml("AresData.Xml");

 

    例:
        .......
        custOrderRel.Nested = true;    //DataRelation对象的Nested属性通知将相关表,嵌套在XML输出中每个父客户之下。
        thisDataSet.WriteXml(@"c:/..../AresData.xml");     //调用WriteXml(),将DataSet数据按XML格式写入文件中。

    从XML读取到DataSet中:

        .......

        DataSet thisDataSet = new DataSet();

        thisDataSet.ReadXml(@"c:/..../AresData.xml");    //ReadXml()方法读取XML文档到thisDataSet对象中。

 

        foreach(DataRow custRow in thisDataSet.Tables["Customers"].Rows)  //所创建的DataTable采用XML文档中的根元素命名。
        {                                                                  //可以使用DataTable的TableName属性,输出DataSet的DataTable名称。如:thisDataSet.Tables[0].TableName.
            Console.WriteLine(custRow["CustomerID"]);

        }

     
________________
6. 带有WHERE 的SELECT
    SELECT * FROM Customers WHERE CustomerID = "ZZ009"
    SELECT * FROM Orders WHERE OrderID BETWEEN 10900 AND 10999

________________
7.DataAdapter 对象中的SQL命令
    注:ADO.NET对象模型 和 C#  要比 SQL 更适合处理复杂运算 和 导航逻辑(比如,查找相关的另一个表的数据)

         所以,可以把数据填充到DataSet中,在客户机上执行这种逻辑。

    
    查看SQL SELECT、UPDATE、INSERT 和 DELETE命令:

    命令构建器(command builder)用于根据SELECT命令生成SQL命的UPDATE、INSERT和DELETE)命令。

    可以用CommandBuilder对象的GetUpdateCommand()、GetInsertCommand()和GetDeleteCommand()方法生成命令。

    例:

        SqlConnection thisConnection = new SqlConnection(@".........ConnectString...........");
        thisConnection.Open();
        SqlDataAdapter thisAdapter = new SqlDataAdapter("SELECT CustomerID FROM Customers", thisConnection);
        SqlCommandBuilder thisBuilder = new SqlCommandBuilder(thisAdapter);    //用Command builder构建命令

 

        SqlCommand updateCommand = thisBuilder.GetUpdateCommand();

        Console.WriteLine(updateCommand.CommandText);    // 输出builder构建的SQL命令,可以看到SQL命令是什么样的,

                                                                                //比如:UPDATE [Customer] SET [CustomerID] = @p1 WHERE ......
        SqlCommand insertCommand = thisBuilder.GetInsertCommand();

        Console.WriteLine(insertCommand.CommandText);   

 

        SqlCommadn deleteCommand = thisBuilder.GetDeleteCommand();

        Console.WriteLine(deleteCommand.CommandText);

 

        DataAdapter还有SelectCommand,UpdateCommand,InsertCommand和DeleteCommand属性,可以直接获取 和 设置 更新时使用的SQL命令。

________________
8.直接执行SQL命令
    执行面向集合的操作(比如,更新满足条件的一组数据)可以直接用SQL命令,要比用C#扩展的SQL指令更有效。

    ADO.NET 提供了 SqlCommand 和 OleDbCommand对象,他们提供了可直接执行SQL命令的方法。


    提取单值:

     例:

        .....

        SqlConnection thisConnection = new SqlConnection(@".........ConnectString.........");

        thisConnection.Open();

        SqlCommand thisCommand = thisConnection.CreateCommand();

        thisCommand.CommandText = "SELECT COUNT (*) FROM Customers ";   

        Object countResult = thisCommand.ExecuteScalar();   

        Console.WriteLine(countResult);    //输出查询到的记录数目

        thisConnection.Close();

 

    不检索数据:

    类似SQL INSERT, UPDATE, DELETE的修改操作不需要返回数据,只需要知道影响的行数。

    用ExecuteNonQuery()方法。

    例:

        ......

        thisCommand.CommandText = "UPDATE Products SET UnitPrice=UnitPrice*1.05 WHERE SupplierId=12";

        int rowAffected = thisCommand.ExecuteNonQuery();    //执行后,只返回影响的行数

        Console.WriteLine(rowAffected);

        thisConnection.Close();

________________
9.调用SQL存储过程  

    存储过程在一个单元中封装了复杂的SQL查询和数据过程,可以由多个程序或用户之间调用。

    例:

        ......

        SqlConnection thisConnection = new SqlConnection(@"...........ConnectionString..............");

        thisConnection.Open();

        SqlCommand thisCommand = thisConnection.CreateCommand();

        thisCommand.CommandType = CommandType.StoredProcedure;    //将SqlCommand对象的命令属性设为 存储过程类型。

                                                                                            //CommandType.StoreProcedure是ADO.NET的一个枚举
        thisCommand.CommandText = "Ten Most Expensive Products";    //"Ten Most Expensive Products"是一个存储过程的名称

        SqlDataReader thisReader = thisCommand.ExecuteReader();


        while(thisReader.Read())

            Console.WriteLine(thisReader[UnitePrice]); //UnitePrice是列名

 

________________
10.使用LINQ over DataSet
     LINQ over DataSet工具联合使用LINQ 和 ADO.NET。是LINQ to Entity(属于高级内容)功能的一小部分。
     它使用System.Data.DataSetExtensions名称空间,由VS自动添加。不需要手动using,只要using System.Data.Linq。
     例:
        .....
        //ADO.NET代码

        ........        
        custAdapter.Fill(thisDataSet, "Customers");    //用ADO.NET填充

        orderAdapter.Fill(thisDataSet,"Orders");

        DataRelation custOrderRel = thisDataSet.Relations.Add("CustOrders",      //建立表Orders 和 Customers之间的关系
                            thisDataSet.Tables["Customers"].Columns["CustomerID"],
                            thisDataSet.Tables["Orders"].Columns["CustomerID"]);

        //下面是LINGQ代码

        var customers = thisDataSet.Tables["Customers"].AsEnumerable();    //将表赋值给var对象

        var orders = thisDataSet.Tables["Orders"].AsEnumerable();

 

        var preferredCustomers =                     //用LINQ查询数据
                from c in customers

                where c.GetChildRows("CustOrders").Length»10

                orderby c.GetChildRows("CustOrders").Length

                select c;

 

        foreach(var customer in preferredCustomers)

        {
            Console.WriteLine("{0} orders: {1} {2}",        
                  customer.GetChildRows("Custorders").Length,         
                  customer["CustomerID"], customer["CompanyName"]);
        }

 

________________
LINQ to XML
LINQ to XML并不打算替代标准的XML API,只是补充了这些标准XML类
11.LINQ to XML函数构造方法
    函数构建方式(functional construction):

    在这种方式中,构造函数的调用可以用反映XML文档结构的方式嵌套。

    例:

        .....

        XDocument xdoc = new XDocument(    //XCocument 表示完整的XML文档
                new XELement("customers",
                        new XElement("customer",
                                 new XAtrribute("ID","A"),    
                                 new XAtrribute("City","New York"),
                                 new XAtrribute("Region","North America"),
                                 new XElement("order",
                                        new XAtrribute("Item","Widget"),
                                        new XAtrribute("Price",100)
                                      )
                        ),
                        new XElement("customer",
                                "AAAAA",

                                new XAtrribute("ID","B"),
                                new XAtrribute("City","Mumbai")
                                
                )
        );
        Console.WriteLine(xdoc);

        Console.ReadLine();

        .....

        输出结果:
        «customers»

            «customer ID="A" City="New York" Region="North America"»

                «order Item="Widget" Price="100" /»
            «/cutomer»   

            «customer ID="B" City="Mumbai" Region="Asia"»AAAAA«/customer»
        «/customers»

     *********************************

         XML的属性是叶节点,所以不包含其他节点,只有属性名称和值.

         其他构造函数:XDeclaration()用于XML文档开头的声明; XComment()用于XML注释。

________________
12.保存和加载XML文档
     Save()方法&Load()方法:

     在用LINQ to XML方法Save()把XML文档保存到文件时,会自动创建文档开头的声明,一般不需要用XDeclaration()来创建。
     XDocument.Load()是静态的,可以加载由别的程序创建的文档,创建XDocument实例。

     例:

         XDocument xdoc = new XDocument(..............);

         string xmlFileName = @"C:/....../example.xml";

         xdoc.Save(xmlFileName);    //将构造好的XML文档,存储为文件


         XDocument xdoc2 = XDocument.Load(xmlFileName);    //将磁盘中的文档读取出来

         Cosole.WriteLine(xdoc2);

         ......

                 
     从字符串加载XML:

        XDocument xdoc = XDocument.Parse(@"«customers».......«/customers»"); //Parse通过字符串创建XML文档

 

    声明一个ASCII码的XML文档头:

        xdoc.Declaration = new XDeclaration("1.0","us-ascii","yes");

________________
13.处理XML片段
    处理片段时,只是把XElement(而不是XDocument)当作顶级XML对象。

    片段的唯一限制是,不能添加比较节点类型,例如:XComment,XDeclaration,XProcessingInstruction(用于XML处理指令)。

    例:
        XElement xcust = new XElement( new XElement(......)..........);

    注意:这两个类都实现了Load()和Save()方法,XElemnt 和 XDocument继承自LINQ to XML类的XContainer;
            在XDocument上执行的大多数操作,在XElement上也可以执行。

________________
14.通过LINQ to XML生成 XML
    XML常常用语在客户机和服务器之间交流数据,或者多层应用程序之间交流。

    用LINQ to SQL查询数据,再用LINQ to XML吧数据转换为XML.

    例:

        .......

        AreslabDataContext aresData = new aresData();    //创建DataContext实例

        XElement aresCustomerOrders = new XElement("customers",    //创建XML片段实例
                      from c in aresData.Customers            //利用LINQ查询数据,DataContext对象的Customers成员作为数据源
                      select new XElement("customer",        //构建select投射
                                      new XAtrribute("ID", c.CustomerID),
                                      new XAtrribute("Company", c.CompanyName),  
                                              from o in c.orders
                                              select new XElement("order",
                                                      new XAtrribute("orderID",o,OrderID),
                                                      new XAtrribute("orderTotal", o.Order_Detail.Sum(od=»od.Quantity*od.UnitPrice))
                                      ) //end order
                        )    //end customer
         );    //end customers

        string xmlFileName = "c:/.../aresCustomerOrders.xml";

        aresCustomerOrders.Save(xmlFileName);

________________
15.查询XML文档
    LINQ to XML类提供属性和方法,返回可查询的类的对象集合。

    将XML对象作为LINQ查询对象:

     .......

    XDocument customers = XDocument.Load(xmlFileName);

    var queryResult = from c in customers.Elements() select c.Name;


    使用查询成员

        1)Element():返回文档 或 片段中的第一个元素。文档的话就返回根元素;
        2)Descendants():返回文档 或 片段中的所有子元素(所有级别);
            例:queryResults = from c in customers.Descendants() select c.Name;
                 foreach (var item in queryResults.Distinct()) //筛选出不同的元素

                 Descendants(string)重载:
                 queryResults = from c in customers.Desendants("customer") select c;  //查询指定名称的子元素,返回所有customer元素。

        3)Ancestors():返回比源元素级别高的一组元素;

        4)Attribute():返回当前选中元素的所有属性;

            例:queryResults = from c in customers.Descendants("customer").Attributes() select c; //返回customers中所有customer元素的属性值

                     显示c的话是:ID City Company ....ID City Company.............

                 Attribute(sting)重载:
                 queryResults = from c in customers.Descendants("customer").Attribute("Company")//返回指定属性对象:Company=“Toms Spezialit”
                                      select c.Value;    //用Value属性获得属性值 
                  int min = queryResults.Min(); //取记录中的最小值

________________

目录
相关文章
MessageBox.Show()的各种用法
winform MessageBox.Show Api整体说明介绍
194 0
|
3天前
|
SQL 关系型数据库 分布式数据库
Doodle Jump — 使用Flutter&Flame开发游戏真不错!
用Flutter&Flame开发游戏是一种什么体验?最近网上冲浪的时候,我偶然发现了一个国外的游戏网站,类似于国内的4399。在浏览时,我遇到了一款经典的小游戏:Doodle Jump...
|
11天前
|
弹性计算 运维 安全
访问控制(RAM)|云上程序使用临时凭证的最佳实践
STS临时访问凭证是阿里云提供的一种临时访问权限管理服务,通过STS获取可以自定义时效和访问权限的临时身份凭证,减少长期访问密钥(AccessKey)泄露的风险。本文将为您介绍产品原理,以及具体的使用步骤。
151031 3
|
9天前
|
数据采集 存储 运维
提升团队工程交付能力,从“看见”工程活动和研发模式开始
本文从统一工程交付的概念模型开始,介绍了如何将应用交付的模式显式地定义出来,并通过工具平台落地。
119980 55
|
10天前
|
监控 负载均衡 Java
深入探究Java微服务架构:Spring Cloud概论
**摘要:** 本文深入探讨了Java微服务架构中的Spring Cloud,解释了微服务架构如何解决传统单体架构的局限性,如松耦合、独立部署、可伸缩性和容错性。Spring Cloud作为一个基于Spring Boot的开源框架,提供了服务注册与发现、负载均衡、断路器、配置中心、API网关等组件,简化了微服务的开发、部署和管理。文章详细介绍了Spring Cloud的核心模块,如Eureka、Ribbon、Hystrix、Config、Zuul和Sleuth,并通过一个电商微服务系统的实战案例展示了如何使用Spring Cloud构建微服务应用。
103493 8
|
11天前
|
人工智能 Serverless 对象存储
让你的文档从静态展示到一键部署可操作验证
通过函数计算的能力让阿里云的文档从静态展示升级为动态可操作验证,用户在文档中单击一键部署可快速完成代码的部署及测试。这一改变已在函数计算的活动沙龙中得到用户的认可。
120749 207
|
11天前
|
SQL 存储 数据可视化
Ganos H3地理网格能力解析与最佳实践
本文介绍了Ganos H3的相关功能,帮助读者快速了解Ganos地理网格的重要特性与应用实践。H3是Uber研发的一种覆盖全球表面的二维地理网格,采用了一种全球统一的、多层次的六边形网格体系来表示地球表面,这种地理网格技术在诸多业务场景中得到广泛应用。Ganos不仅提供了H3网格的全套功能,还支持与其它Ganos时空数据类型进行跨模联合分析,极大程度提升了客户对于时空数据的挖掘分析能力。
|
10天前
|
存储 缓存 安全
深度解析JVM世界:JVM内存结构
深度解析JVM世界:JVM内存结构
|
17天前
|
人工智能 编解码 对象存储
一键生成视频!用 PAI-EAS 部署 AI 视频生成模型 SVD 工作流
本教程将带领大家免费领取阿里云PAI-EAS的免费试用资源,并且带领大家在 ComfyUI 环境下使用 SVD的模型,根据任何图片生成一个小短视频。