访问量不大的项目我都是用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 [email protected] WHERE id [email protected]"; 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()