分享

手把手教你用好LINQ to SQL(2)

 gingging 2010-01-26
    作者写下这篇文章的主要目的不是“一口吃成个胖子”让大家一次就学会LINQ to SQL。而是从不同的方面帮助大家正确理解,所以这里提到的快速的含义是提高效率,而不是单纯为了学习的速度。

    Step3:根据数据库表自动生成代码

    当建好Linq to SQL Classes后,VS主界面中自动打开了这个文件。可以看到,这 个文件实际是一个设计文件,目前还不包含任何代码和元素。下一步就是利用我们刚才的数据 库自动生成ORM代码了。

    打开Server Explorer面板。一般它位于VS的左上角,如果没有,请到View菜单中去打开。 然后在Date Connections上右键单击,选择“Add Connection”,从这里添加对数据库 MyBulletin的连接。

    03

    图3、添加数据库连接

    如图3所示,在Server name中填入SQL Server数据库服务的名字,如果使用的是SQL Server Express 2005,服务名一般是“计算机名\SQLEXPRESS”的格式,然后在“Select or enter a database name”中选择MyBulletin,单击“OK”,就连上我们所需的数据库了。

    这时,展开这个连接下的Tables节点,应该能看到Category和Bulletin两个表,选中两个表 ,将它们拖到DataClasses.dbml的设计区,就会看到如图4所示的样子。

    04

    图4、设计视图

    然后,按Ctrl+S保存,OK!ORM构建完了!

    没有骗你,所有需要的代码已经生成完成,现在可以使用它们操作MyBulletin数据库了。不 要怀疑,Linq to SQL使用起来就是这么轻松加愉快,不需要写一行代码,也不需要写一个XML 字符,ORM就构建完了!

    我知道你没看到生成的东西可能不太放心,那么你可以在Solution Explorer里展开 DataClasses.dbml节点,看到里面的DataClasses.designer.cs文件没,打开它,里面就是刚才 自动生成的代码,我们的数据访问操作就靠这些代码了。另外顺表提一下,数据库的连接字符 串放在工程根目录下的app.config文件里,这也是自动生成的,打开它,就可以看到连接字符 串。以后如果要修改连接字符串,就修改这里。

    好了,ORM构建好了,下面我们看看怎么用。

    Step4:使用Linq to SQL访问数据库

    我们首先新建一个工程。为了简单起见,我们就直接建立一个C# Console Application测试 我们的ORM吧。将这个工程命名为LinqToSqlDemo.Test。当然,建好工程后,不要忘了添加对工 程LinqToSqlDemo.Orm的引用,还要添加对“System.Data.Linq”命名空间的引用。

    然后,我们打开Program.cs文件,将其中的内容替换为如下测试代码。

     using System;
            using System.Collections.Generic;
            using System.Data.Linq;
            using System.Linq;
            using System.Text;
            using LinqToSqlDemo.Orm;
            namespace LinqToSqlDemo.Test
            {
            class Program
            {
            private static DataClassesDataContext dataContext = new DataClassesDataContext();
            private static void Output()
            {
            //输出分类信息
            foreach (Category c in dataContext.Categories)
            {
            Console.WriteLine("分类" + c.ID + ":" + c.Name);
            }
            //输出体育新闻下的公告信息
            Category categorySport = dataContext.Categories.Single(c => c.Name == "体育新闻");
            foreach (Bulletin b in categorySport.Bulletins)
            {
            Console.WriteLine("标题:" + b.Title);
            Console.WriteLine("内容:" + b.Content);
            Console.WriteLine("发布日期:" + b.Date);
            Console.WriteLine("所属分类:" + b.Category1.Name);
            }
            }
            private static void TestInsert()
            {
            //生成分类实体类
            Category category1 = new Category()
            {
            Name = "国际要闻"
            };
            Category category2 = new Category()
            {
            Name = "体育新闻"
            };
            Category category3 = new Category()
            {
            Name = "财经快报"
            };
            //生成公告实体类
            Bulletin bulletin1 = new Bulletin()
            {
            Content = "曼联晋级冠军杯四强",
            Date = DateTime.Now,
            Title = "曼联晋级冠军杯四强"
            };
            Bulletin bulletin2 = new Bulletin()
            {
            Content = "18:00直播亚冠首尔VS山东,敬请期待!!!",
            Date = DateTime.Now,
            Title = "18:00直播亚冠首尔VS山东"
            };
            //将公告加入相应分类
            category2.Bulletins.Add(bulletin1);
            category2.Bulletins.Add(bulletin2);
            //加入数据库
            dataContext.Categories.InsertOnSubmit(category1);
            dataContext.Categories.InsertOnSubmit(category2);
            dataContext.Categories.InsertOnSubmit(category3);
            dataContext.SubmitChanges();
            }
            private static void TestDelete()
            {
            dataContext.Categories.DeleteOnSubmit(dataContext.Categories.Single(c => c.Name == "国际要闻"));
            dataContext.SubmitChanges();
            }
            private static void TestUpdate()
            {
            Category categoryFinance = dataContext.Categories.Single(c => c.Name == "财经快报");
            categoryFinance.Name = "财经新闻";
            dataContext.SubmitChanges();
            }
            static void Main(string[] args)
            {
            Console.WriteLine("==============================Linq to SQL 测试==============================");
            Console.WriteLine();
            Console.WriteLine("==============================测试Insert==============================");
            Console.WriteLine();
            TestInsert();
            Output();
            Console.WriteLine("==============================测试Delete==============================");
            Console.WriteLine();
            TestDelete();
            Output();
            Console.WriteLine("==============================测试Update==============================");
            Console.WriteLine();
            TestUpdate();
            Output();
            Console.ReadLine();
            }
            }
            }
            
    
            

     

    一下子看不懂上述代码页没有关系,稍候我们会解释一下。现在,我们先来看运行结果:

    06

    图5、测试程序运行结果

    我们先来看看这段测试程序做了什么事。刚开始,数据库是空的,我们首先插入三个分类, 并在“体育新闻”下插入两条公告,这是对Insert的测试。接着,我们删除了“国际要闻”分 类,这是对Delete的测试。然后,我们将“财经快报”改为“财经新闻”,这是对Update测试 。另外,整个过程的输出当然是对Select的测试。这样,数据库基本的操作都测试过了。从输 出结果来看,我们的ORM组件运行很顺利,程序输出正确。

    程序分析

    经过简单的四步,我们就完成了通过Linq to SQL操作数据库的过程。下面我们对 测试代码进行一个简要的分析,帮助朋友们学会Linq to SQL操作数据库的基本方法。

    取得数据库Gateway

    要操作数据库,我们首先要获得一个DataContext对象,这个对象相当于一个数据 库的Gateway,所有的操作都是通过它进行的。这个对象的名字是“Linq to SQL Classes文件 名+‘DataContext’”,这里,就是DataClassesDataContext了。它和普通对象一样,直接实 例化就行了。在Demo里我将它实例化为一个静态变量。

    取得DataContext对象后,每个数据表就会映射到其一个集合属性,例如Category表映射到 dataContext.Categories,这是一个集合属性,每一个元素是一个实体类,代表此表中的一条 记录。实体类名和表名相同。实体类的字段自然就映射到对应表的字段。

    还有一点需要注意,数据库中的一对多关系,在Linq to SQL生成代码时会自动表示到类结 构中。并且,这种关联是双向的。例如,Category与Bulletin的一对多关系,到了类结构中, 反映成如下形式:在Category类中,有一个名为Bulletins的集合属性,内容是所有属于此 Category的Bulletin对象的引用。而在Bulletin类中,也会有个Category1属性(由于Category 这个名字被我们用了,所以,这个关联属性自动加了个“1”),其内容是此Bulletin所属 Category对象的引用。

    Insert操作

    Insert用于向数据库添加记录。一般情况下,使用“DataContext.表映射集 合.InsertOnSubmit(实体类)”的方式就可以完成Insert操作。不过这里要注意一点,由于Linq to SQL使用了“Unit of Work”模式,所以,对数据库的操作不会立即提交到数据库,而要调 用DataContext的SubmitChanges方法,所有改动才会被提交到数据库。

    Delete操作

    Delete操作用于从数据库中删除记录。表映射集合的DeleteOnSubmit方法可以实 现这个操作。这个方法需要一个参数,就是要删除的实体类,这里不能直接传个ID去删除,要 首先通过ID找到相应实体类,传给DeleteOnSubmit再删除。当然最后不要忘了SubmitChanges。

    Update操作

    Update操作用于更新数据库中某已存在记录的信息。在Linq to SQL中,Update操 作就是首先加载相应的实体类,修改其相应字段后,SubmitChanges就可以了。

    Select操作

    Select操作用于从数据库中返回指定的记录。在Linq to SQL中,查询结果都是以实体类或 实体类集合的方式返回的。其中实体类集合并不是List,如果想转为List,只需在返回结果上 调用ToList方法即可。

    如果是查询单一记录,建议使用表映射集合的Single方法。至于查询参数,建议采用lambda 表达式。如果你对lambda表达式不熟,可以参考这里http://msdn.microsoft.com/zh- cn/library/bb397687.aspx

    其它相关示例代码

    常用Select操作举例

    取得单个记录(ID为3的分类)

    RETURNDATACONTEXT.CATEGORIES.SINGLE(C=>C.ID==3;

    取得全部记录(全部分类)

    RETURNDATACONTEXT.CATEGORIES;

    得部分记录(所属分类ID为3的公告,按ID降序排列)

    RETURNFROMBorderbyb.IDdescending
                        

    selectb;

    取得部分记录并分页,最后转换为List(所属分类ID为3的公告并分页,pageSize为每页多 少条记录,pageNo为第几页)

                        

    varbulletins=frombINDATACONTEXT.BULLETINS

    orderbyb.IDdescending

    selectb;

    总结

    好了,这篇文章就到这里了。希望能帮助大家快速上手Linq to SQL。关于Linq to SQL,还 有许多丰富的功能和细节问题,篇幅原因不能详述,各位可以参考相关资料。

    编者附注

    网友wiken chan在跟着程序写了一遍后,发现文中代码部分,表名部分均由出错,与本文介绍中建立的表名有出入,并进行了更正测试。在此向网友wiken chan表示感谢。

            
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Data.Linq;  
    4. using System.Linq;  
    5. using System.Text;  
    6. using LinqToSqlDemo.Orm;  
    7. namespace LinqToSqlDemo.Test  
    8. {  
    9.     class Program  
    10.     {  
    11.         private static DataClassesDataContext dataContext = new DataClassesDataContext();  
    12.         private static void Output()  
    13.         {  
    14.             //输出分类信息  
    15.             foreach (Category c in dataContext.Category)  
    16.             {  
    17.                 Console.WriteLine("分类" + c.ID + ":" + c.Name);  
    18.             }  
    19.             //输出体育新闻下的公告信息  
    20.             Category categorySport = dataContext.Category.Single(c => c.Name == "体育新闻");  
    21.             foreach (Bulletin b in categorySport.Bulletin)  
    22.             {  
    23.                 Console.WriteLine("标题:" + b.Title);  
    24.                 Console.WriteLine("内容:" + b.Content);  
    25.                 Console.WriteLine("发布日期:" + b.Date);  
    26.                 Console.WriteLine("所属分类:" + b.Category1.Name);  
    27.             }  
    28.         }  
    29.         private static void TestInsert()  
    30.         {  
    31.             //生成分类实体类  
    32.             Category category1 = new Category()  
    33.             {  
    34.                 Name = "国际要闻" 
    35.             };  
    36.             Category category2 = new Category()  
    37.             {  
    38.                 Name = "体育新闻" 
    39.             };  
    40.             Category category3 = new Category()  
    41.             {  
    42.                 Name = "财经快报" 
    43.            };  
    44.             //生成公告实体类  
    45.             Bulletin bulletin1 = new Bulletin()  
    46.             {  
    47.                 Content = "曼联晋级冠军杯四强",  
    48.                 Date = DateTime.Now,  
    49.                 Title = "曼联晋级冠军杯四强" 
    50.             };  
    51.             Bulletin bulletin2 = new Bulletin()  
    52.             {  
    53.                 Content = "18:00直播亚冠首尔VS山东,敬请期待!!!",  
    54.                 Date = DateTime.Now,  
    55.                 Title = "18:00直播亚冠首尔VS山东" 
    56.             };  
    57.             //将公告加入相应分类  
    58.            category2.Bulletin.Add(bulletin1);  
    59.             category2. Bulletin.Add(bulletin2);  
    60.             //加入数据库  
    61.             dataContext.Category.InsertOnSubmit(category1);  
    62.             dataContext. Category.InsertOnSubmit(category2);  
    63.             dataContext. Category.InsertOnSubmit(category3);  
    64.             dataContext.SubmitChanges();  
    65.         }  
    66.         private static void TestDelete()  
    67.         {  
    68.             dataContext.Category.DeleteOnSubmit(dataContext.Category.Single(c => c.Name == "国际要闻"));  
    69.             dataContext.SubmitChanges();  
    70.         }  
    71.         private static void TestUpdate()  
    72.         {  
    73.             Category categoryFinance = dataContext.Category.Single(c => c.Name == "财经快报");  
    74.             categoryFinance.Name = "财经新闻";  
    75.             dataContext.SubmitChanges();  
    76.         }  
    77.         static void Main(string[] args)  
    78.         {  
    79.             Console.WriteLine("==============================Linq to SQL 测试==============================");  
    80.             Console.WriteLine();  
    81.             Console.WriteLine("==============================测试Insert==============================");  
    82.             Console.WriteLine();  
    83.             TestInsert();  
    84.             Output();  
    85.             Console.WriteLine("==============================测试Delete==============================");  
    86.             Console.WriteLine();  
    87.             TestDelete();  
    88.             Output();  
    89.             Console.WriteLine("==============================测试Update==============================");  
    90.             Console.WriteLine();  
    91.             TestUpdate();  
    92.             Output();  
    93.             Console.ReadLine();  
    94.        }  
    95.     }  

     

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多