常用的数据库操作
本篇概述
本篇描述一些常用的数据库操作,包括:条件查询、排序、分页、事务等基本数据库操作。试验的数据库为MySQL。
1 条件查询
- 查询所有记录
List<Article> articles = _context.Articles.ToList<Article>();
- 根据主键进行查询
Article article = _context.Articles.Find(id);
- 根据非主键信息字段进行查询
List<Product> products = _context.Products .Where(p => p.Name == name) .ToList<Product>();
如果找不到会返回Null,但不报异常。
- 查询一条记录
Article articles = _context.Articles
.Single(article=>article.Title==title);
此时应要求该字段做唯一性约束,该方法期待必须返回一条记录,0条和多条都会报异常。 而First方法会取众多记录中的第一条,如果找不到会报异常,但有多条符合条件就取一条不报异常。
Article articles = _context.Articles
.First(article=>article.Title.Contains(title));
- 模糊查询 模糊查询有两种方法:
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中的日志级别就可以了。
2 排序
List<Article> articles = _context
.Articles.OrderBy(article=>article.Title)
.ToList<Article>();
List<Article> articles = _context
.Articles.OrderByDescending(article=>article.Title)
.ToList<Article>();
3 预先加载¶
可以使用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>();
4 非跟踪查询(No-tracking queries)¶
如果仅仅是只读查询,采用非跟踪查询会提供查询的性能。
List<Article> articles = _context.Articles .AsNoTracking() .ToList<Article>();
5 原始的 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 注入式攻击
6 分页
int pageSize = 10; int pageNumber = 2; List<Article> articles = _context.Articles .AsNoTracking() .Skip(pageSize* pageNumber) .Take(pageSize) .ToList<Article>();
修改数据
- 添加数据
使用DbSet.Add方法将添加的实体类的新实例。
var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
context.SaveChanges();
- 更新数据
var blog = context.Blogs.Find("xx");
blog.Url = "http://sample.com/blog";
context.SaveChanges();
- 删除数据
var blog = context.Blogs.First(); context.Blogs.Remove(blog); context.SaveChanges();
- 在单个 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();
8 使用连接池
String connStr = Configuration.GetConnectionString("MySQLConnection");
services.AddDbContextPool<SalesContext>(builder=> builder.UseMySQL(connStr));
建议尽量使用连接池方式连接数据库。
版权声明:
本文为智客工坊「seabluescn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
