循序渐进学.Net Core Web Api开发系列【9】:常用的数据库操作
系列目录
本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi
一、概述
本篇描述一些常用的数据库操作,包括:条件查询、排序、分页、事务等基本数据库操作。试验的数据库为MySQL。
二、条件查询
1、查询所有记录
List<Article> articles = _context.Articles.ToList<Article>();
2、根据主键进行查询
Article article = _context.Articles.Find(id);
3、根据非主键信息字段进行查询
List<Product> products = _context.Products .Where(p => p.Name == name) .ToList<Product>();
如果找不到会返回Null,但不报异常。
4、查询一条记录
Article articles = _context.Articles
.Single(article=>article.Title==title);
此时应要求该字段做唯一性约束,该方法期待必须返回一条记录,0条和多条都会报异常。
而First方法会取众多记录中的第一条,如果找不到会报异常,但有多条符合条件就取一条不报异常。
Article articles = _context.Articles
.First(article=>article.Title.Contains(title));
5、模糊查询
模糊查询有两种方法:
List<Article> articles = _context.Articles .Where(article => article.Title.Contains(title)) .ToList(); List<Article> articles = _context.Articles .Where(article => EF.Functions.Like(article.Title,$"{title}%")) .ToList();
Like方法和String的Contains方法都能实现模糊查询,主要区别在于:EF.Functions.Like()方法支持通配符,而StartsWith、Contains和EndsWith方法是不支持通配符的,比较下面两个方法,第1条语句可以实现预期效果,但第2条语句不行。
(1) EF.Functions.Like(article.Title,“%[a-z]%”) (2) article.Title.Contains("[a-z]")
提示:如果需要查看实际执行的SQL语句,修改application.json中的日志级别就可以了。
三、排序
List<Article> articles = _context .Articles.OrderBy(article=>article.Title) .ToList<Article>(); List<Article> articles = _context .Articles.OrderByDescending(article=>article.Title) .ToList<Article>();
四、 预先加载
可以使用Include方法,以便指定要包含在查询结果的相关的数据。
Article article = _context.Articles .Include(a => a.author) .First();
上述代码中article的author属性不再为null。
加载多项
var blogs = context.Blogs .Include(blog => blog.Posts) .Include(blog => blog.Owner) .ToList();
多级预加载:
List<Column> columns = _context.Columns .Include(column => column.Articles) .ThenInclude(article=> article.author) .ToList<Column>();
五、非跟踪查询(No-tracking queries)
如果仅仅是只读查询,采用非跟踪查询会提供查询的性能。
List<Article> articles = _context.Articles
.AsNoTracking()
.ToList<Article>();
六、原始的 SQL 查询
可以使用FromSql扩展方法,实现基于原始的 SQL 查询的 LINQ 查询。
List<Article> articles = _context.Articles .FromSql("select * from cms_article") .ToList();
也可以使用原始的 SQL 查询来执行存储的过程。
var blogs = context.Blogs .FromSql("EXECUTE dbo.GetMostPopularBlogs") .ToList();
或者实现带参数的查询
var sql = $"select * from cms_article where title like '%{titlewithsql}%'"; List<Article> articles = _context.Articles .FromSql(sql) .ToList();
预加载Include、Where 与OrderBy都可以使用
List<Article> articles = _context.Articles .FromSql(sql) .Include(a=>a.author) .ToList(); var searchTerm = ".NET"; var blogs = context.Blogs .FromSql($"SELECT * FROM dbo.SearchBlogs({searchTerm})") .Where(b => b.Rating > 3) .OrderByDescending(b => b.Rating) .ToList();
注意:如果使用字符串串联来动态生成的查询字符串的任何部分,则你将负责验证任何输入,以防止受到 SQL 注入式攻击
七、分页
int pageSize = 10; int pageNumber = 2; List<Article> articles = _context.Articles .AsNoTracking() .Skip(pageSize* pageNumber) .Take(pageSize) .ToList<Article>();
八、修改数据
1、添加数据
使用DbSet.Add方法将添加的实体类的新实例。
var blog = new Blog { Url = "http://sample.com" }; context.Blogs.Add(blog); context.SaveChanges();
2、更新数据
var blog = context.Blogs.Find("xx"); blog.Url = "http://sample.com/blog"; context.SaveChanges();
3、删除数据
var blog = context.Blogs.First(); context.Blogs.Remove(blog); context.SaveChanges();
4、在单个 SaveChanges 的多个操作
context.Blogs.Add(new Blog { Url = "http://sample.com/blog_one" }); context.Blogs.Add(new Blog { Url = "http://sample.com/blog_two" }); // update var firstBlog = context.Blogs.First(); firstBlog.Url = ""; // remove var lastBlog = context.Blogs.Last(); context.Blogs.Remove(lastBlog); context.SaveChanges();
SaveChanges是事务性的,以上代码不需要额外增加任何事务性代码。
九、 使用连接池
String connStr = Configuration.GetConnectionString("MySQLConnection"); services.AddDbContextPool<SalesContext>(builder=> builder.UseMySQL(connStr));
建议尽量使用连接池方式连接数据库。
签名区:
如果您觉得这篇博客对您有帮助或启发,请点击右侧【推荐】支持,谢谢!