zoukankan      html  css  js  c++  java
  • dapper使用

    dapper使用

     

    访问量不大的项目我都是用EF写数据库操作,因为EF除了速度上慢以外,但开发效率极快,省略了很多sql写法,并能很方便的调用外键、集合等信息,用EF写项目最爽的事。不过有些项目网站要考虑运行速度,这时不得不用其它的ORM框架,我常用dapper,因为它效果快,而且写sql非常灵活,接下来面写一些方法看看dapper的使用

    1、连接语句

    var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlDiagnosticsDb"].ConnectionString);

    使用dapper不需要考虑conn是否连接,在执行dapper时自行判断 open状态,如果没有打开它会自己打开。

    2、insert

    string query = "INSERT INTO Book(Name)VALUES(@name)";
    conn.Execute(query, book);

    book类中有name属性,就可以这样方便去写,当然也可以写成

    string query = "INSERT INTO Book(Name)VALUES(@name)";
     conn.Execute(query,  new{@name=book.name});

    3、update

    string query = "UPDATE Book SET  Name=@name WHERE id =@id";
     conn.Execute(query, book);

    4、 delete

    string query = "DELETE FROM Book WHERE id = @id";
    conn.Execute(query, book);
    conn.Execute(query, new { id = id });

    5、query

    复制代码
    string query = "SELECT * FROM Book";
    //无参数查询,返回列表,带参数查询和之前的参数赋值法相同。
     conn.Query<Book>(query).ToList();
    
     //返回单条信息
     string query = "SELECT * FROM Book WHERE id = @id";
     book = conn.Query<Book>(query, new { id = id }).SingleOrDefault();  
    复制代码

    6、 传统sql in (1,2,3) 用dapper就这样写

    conn.Query<Users>("SELECT * FROM Users s WHERE s.id IN (@ids) ",new { ids = new int[]{1,2,3}})
    
    conn.Query<Users>("SELECT * FROM Users s WHERE s.id IN (@ids) ",new { ids = IDs.ToArray()})

    在dapper因为安全性,不能直接用sql接接    要采用参数化,

    7、批量插入

    conn.Execute(@"insert MyTable(colA, colB) values (@a, @b)", new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } })

    也可以直接写入一个集合

    conn.Execute("insert user(name) values(@name)",users)

    这里users是一个user表的对象集合,可一次把集合中的所有数据插入到数据表中。

    8、多表查询

    复制代码
    //查询图书时,同时查找对应的书评,并存在List中。实现1--n的查询操作
    string query = "SELECT * FROM Book b LEFT JOIN BookReview br ON br.BookId = b.Id WHERE b.id = @id";
    Book lookup = null;
    //Query<TFirst, TSecond, TReturn>
     var b = conn.Query<Book, BookReview, Book>(query,
      (book, bookReview) =>
      {
         //扫描第一条记录,判断非空和非重复
        if (lookup == null || lookup.Id != book.Id)
          lookup = book;
        //书对应的书评非空,加入当前书的书评List中,最后把重复的书去掉。
        if (bookReview != null)
          lookup.Reviews.Add(bookReview);
         return lookup;
      }, new { id = id }).Distinct().SingleOrDefault();
    return b;
    复制代码

    多表联合查询是比较麻烦一些,到现在不是完全明白,多看几个例子

    var sql =  @"select * from Posts p join Users u on u.Id = p.OwnerId Order by p.Id";
    var data = conn.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;},splitOn:"id");
     

    Post类和User类,它们存在外键, conn.Query返回的类型是最后一个参数Post, 其中Post中有一属性Owner是User对象,在(post, user)=>lamda中指定了Owner值,上边的代码中的splitOn是ID,运行时,会从查询结果所有字段列表的最后一个字段开始进行匹配,一直到找到Id这个字段(大小写忽略),找到的第一个ID字段匹配User类的ID属性,那么从ID到最后一个字段都属于User,ID以前的字段都被影射到Post 通过 (post, user) => { return post;},把两个类的实例解析出来。

    9、三表查询,一个是关联主键表(单个对象),一个是关联外键表(集合)。

    复制代码
        public partial class UserInfo  
            {  
                public UserInfo()  
                {  
                    this.Persion = new HashSet<Persion>();  
                    this.MyTYC = new HashSet<MyTYC>();  
                }  
              
                public int id { get; set; }  
                public string name { get; set; }  
                public Nullable<System.DateTime> createTime { get; set; }  
                public Movies Movies { get; set; }  
                public virtual ICollection<MyTYC> MyTYC { get; set; }  
            }  
    复制代码
    复制代码
        public class Movies  
            {  
                public int ID { get; set; }  
                public string Title { get; set; }  
                public string ReleaseDate { get; set; }  
                public string Genre { get; set; }  
                public string Price { get; set; }  
                public UserInfo UserInfo { get; set; }  
          
            }  
    复制代码
    复制代码
        public partial class MyTYC  
            {  
                public int id { get; set; }  
                public string name { get; set; }  
          
            }  
    复制代码
    string sql = @"select * from UserInfo u   
    inner join [Movies].dbo.Movies m on u.id=m.ID   
    inner join MyTYC t on u.id=t.id";  
                var data = conn.Query<UserInfo, Movies, MyTYC, UserInfo>(sql, (u, m, t) => { u.Movies = m; u.MyTYC.Add(t); return u; }); 

    注意这里的对象和集合的获取方法:u.Movies = m; u.MyTYC.Add(t);

    10、多结果查询

    复制代码
    var sql = @"select * from Customers where CustomerId = @id;
     select * from Orders where CustomerId = @id;
     select * from Returns where CustomerId = @id";
    
     using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
     {
            var customer = multi.Read<Customer>().Single();    
            var orders = multi.Read<Order>().ToList();
            var returns = multi.Read<Return>().ToList();
     }
    复制代码

    再来一个

    复制代码
    class Program  
        {  
      
            //创建连接对象  
            protected static SqlConnection GetConnection()  
            {  
                var connection = new SqlConnection("Data Source=.;Initial Catalog=TestDB;Integrated Security=True");  
                connection.Open();  
                return connection;  
            }  
      
            static void Main(string[] args)  
            {  
                //测试输出多个结果集  
                var sql = @"INSERT INTO [dbo].[Student] ([Name]) VALUES ('A1'); select @@IDENTITY as A;  
                            INSERT INTO [dbo].[Student] ([Name]) VALUES ('B1'); select @@IDENTITY as A;  
                            INSERT INTO [dbo].[Student] ([Name]) VALUES ('C1'); select @@IDENTITY as A";  
      
                //初始化数据库连接  
                using (SqlConnection connection = GetConnection())  
                {                  
                    List<int> ilist = new List<int>();  
                    //执行查询,获取结果集集合  
                    var multi = connection.QueryMultiple(sql);  
      
                    //遍历结果集  
                    while(!multi.IsConsumed)  
                    {  
                        //读取当前结果集  
                        var result = multi.Read().ToList()[0].A;  
                        if (result != null)  
                        {  
                            ilist.Add(Convert.ToInt32(result));  
                        }  
                    }  
                    //for(int i = 0;i<3;i++)  
                    //{  
                    //    var result = multi.Read().ToList()[0].A;  
                    //    if (result != null)  
                    //    {  
                    //        ilist.Add(Convert.ToInt32(result));  
                    //    }  
                    //}  
                    foreach (var item in ilist)  
                    {  
                        Console.WriteLine(item.ToString());  
                    }  
                }  
                Console.ReadLine();  
            }  
        } 
    复制代码

    11、如果某一代码中多次操作数据库,可以把conn设置为打开,最后时再close,

    比如:

    复制代码
    conn.open()
    conn.Query(.....
    .....
    for....
    .....
    conn.close()
    复制代码

     转自:https://www.cnblogs.com/lunawzh/p/6607116.html

  • 相关阅读:
    JavaScript学习笔记(六)----内置对象Global 和Math
    JavaScript学习笔记(五)--- String类型
    线性筛素数
    线性筛欧拉函数
    POJ 3090 Visble Lattice Points
    1091 合唱队形(最长上升子序列模板)
    P1018 乘积最大
    P1020 导弹拦截(弱数据)
    P2757 导弹的召唤(数据加强)
    P1313 计算系数
  • 原文地址:https://www.cnblogs.com/wangyu19900123/p/10984970.html
Copyright © 2011-2022 走看看