数据库MySQL,废话不多说,开始今天的代码:
GET:
条件查询:
一、查询所有记录:
List articles = _context.Articles.ToList();
二、根据主键进行查询
Article article = _context.Articles.Find(id);
三、根据非主键信息字段进行查询(如果找不到会返回Null,但不报异常)
List products = _context.Products
.Where(p => p.Name == name)
.ToList();
四、查询一条记录
Article articles = _context.Articles
.Single(article=>article.Title==title);
注意:此时应要求该字段做唯一性约束,该方法期待必须返回一条记录,0条和多条都会报异常。
而First方法会取众多记录中的第一条,如果找不到会报异常,但有多条符合条件就取一条不报异常
五、模糊查询(1)
List articles = _context.Articles
.Where(article => article.Title.Contains(title))
.ToList();
五、模糊查询(2)
List 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]")
排序:
List articles = _context
.Articles.OrderBy(article=>article.Title)
.ToList();
List articles = _context
.Articles.OrderByDescending(article=>article.Title)
.ToList();
预先加载(可以使用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 columns = _context.Columns
.Include(column => column.Articles)
.ThenInclude(article=> article.author)
.ToList();
非跟踪查询(No-tracking queries)
如果仅仅是只读查询,采用非跟踪查询会提供查询的性能。
List articles = _context.Articles
.AsNoTracking()
.ToList();
原始的 SQL 查询
可以使用FromSql扩展方法,实现基于原始的 SQL 查询的 LINQ 查询。
List 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 articles = _context.Articles
.FromSql(sql)
.ToList();
预加载Include、Where 与OrderBy都可以使用
List 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 articles = _context.Articles
.AsNoTracking()
.Skip(pageSize* pageNumber)
.Take(pageSize)
.ToList();
Post:
添加数据
使用DbSet.Add方法将添加的实体类的新实例。
var blog = new Blog { Url = "http://www.vnfan.com" };
context.Blogs.Add(blog);
context.SaveChanges();
更新数据
var blog = context.Blogs.Find("xx");
blog.Url = "http://www.vnfan.com/blog";
context.SaveChanges();
删除数据
var blog = context.Blogs.First();
context.Blogs.Remove(blog);
context.SaveChanges();
在单个 SaveChanges 的多个操作
context.Blogs.Add(new Blog { Url = "http://www.vnfan.com/blog_one" });
context.Blogs.Add(new Blog { Url = "http://www.vnfan.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(builder=> builder.UseMySQL(connStr));
建议尽量使用连接池方式连接数据库。