本文共 6646 字,大约阅读时间需要 22 分钟。
EF可以使用Linq查询、可以使用Lambda查询、可以调用SQL语句。
在代码中添加如下语句可以打印出执行的sql信息,方便查看。
dbContext.Database.Log += c => Console.WriteLine($"sql:{c}");
本次查询使用到的两张表数据如下:
新闻表(News)
新闻类别表(NewsClassify)
Linq查询
1.查询出News表中ID在1,2,3,4,5范围的数据(in查询)。
public static void Show() { using (NewsDbContext dbContext = new NewsDbContext()) { //打印sql信息 dbContext.Database.Log += c => Console.WriteLine($"sql:{c}"); //查询出News表中ID在1,2,3,4,5范围的数据 { var list = from n in dbContext.News where new int[] { 1, 2, 3, 4, 5 }.Contains(n.Id) select n; foreach (var item in list) { Console.WriteLine(item.Title); } } } }
执行结果:
2.分页查询News表,在ID为 2, 6, 7, 8, 9, 10, 11, 12 的数据中,跳过前3条取5条数据。
public static void Show() { using (NewsDbContext dbContext = new NewsDbContext()) { //打印sql信息 dbContext.Database.Log += c => Console.WriteLine($"sql:{c}"); { var list = dbContext.News.Where(n => new int[] { 2, 6, 7, 8, 9, 10, 11, 12 }.Contains(n.Id)) .OrderBy(n => n.Id) .Select(n => new { Title = n.Title, Contents = n.Contents }).Skip(3).Take(5); foreach (var item in list) { Console.WriteLine(item.Title); } } } }
执行结果:
3.表关联,查询两个表中的字段(inner join),查询出新闻标题和新闻类别名称。
public static void Show() { using (NewsDbContext dbContext = new NewsDbContext()) { //打印sql信息 dbContext.Database.Log += c => Console.WriteLine($"sql:{c}"); { var list = from n in dbContext.News join nc in dbContext.NewsClassifies on n.NewsClassifyId equals nc.Id //where new int[] { 2, 6, 7, 8, 9, 10, 11, 12 }.Contains(n.Id) select new { Title = n.Title, Contents = n.Contents, NewsClassifyName = nc.Name }; foreach (var item in list) { Console.WriteLine($"新闻标题:{item.Title},新闻类别:{ item.NewsClassifyName}"); } } } }
执行结果:
4. 表关联,查询两个表中的字段(left join),查询出新闻标题和新闻类别名称。
public static void Show() { using (NewsDbContext dbContext = new NewsDbContext()) { //打印sql信息 dbContext.Database.Log += c => Console.WriteLine($"sql:{c}"); { var list = from n in dbContext.News join nc in dbContext.NewsClassifies on n.NewsClassifyId equals nc.Id into temp from tt in temp.DefaultIfEmpty() select new { Title = n.Title, bname = tt == null ? "" : tt.Name//这里主要第二个集合有可能为空。需要判断 }; foreach (var item in list) { Console.WriteLine($"新闻标题:{item.Title},新闻类别:{ item.bname}"); } } } }
执行结果:
left join和inner join的区别是,left join需要先将查询的结果集放到一个变量中(into temp),然后再对temp中空记录填充默认值,默认值为 NULL(temp.DefaultIfEmpty())。
这里有点问题,按照sql的写法应该是left join ,但是不知道何种原因,EF生成的sql用的是inner join。
关于LINQ处理表关联,可以参考:
Lambda查询
1.查询出News表中ID在1,2,3,4,5范围的数据(in查询)。
public static void Show() { using (NewsDbContext dbContext = new NewsDbContext()) { //打印sql信息 dbContext.Database.Log += c => Console.WriteLine($"sql:{c}"); { var list = dbContext.News.Where(n => new int[] { 1, 2, 3, 4, 5 }.Contains(n.Id));//in查询 list = list.OrderBy(v => v.Id); foreach (var item in list) { Console.WriteLine(item.Title); } } } }
执行结果:
2.查询出News表中Title字段,以‘上’开头,以‘广’结尾,并且包含‘海’的记录。
public static void Show() { using (NewsDbContext dbContext = new NewsDbContext()) { //打印sql信息 dbContext.Database.Log += c => Console.WriteLine($"sql:{c}"); { var list = dbContext.News.Where(n => n.Title.StartsWith("上") && n.Title.EndsWith("广")) .Where(n => n.Title.Contains("海")); foreach (var item in list) { Console.WriteLine(item.Title); } } } }
执行结果:
SQL语句
1.查询News表id=2的记录。
public static void Show() { using (NewsDbContext dbContext = new NewsDbContext()) { //打印sql信息 dbContext.Database.Log += c => Console.WriteLine($"sql:{c}"); { DbContextTransaction trans = null; try { trans = dbContext.Database.BeginTransaction();//开启事物 string sql = "SELECT * FROM News where Id=@Id"; SqlParameter parameter = new SqlParameter("@Id", 2); ListnewList = dbContext.Database.SqlQuery (sql, parameter).ToList(); trans.Commit();//提交事物 foreach (var item in newList) { Console.WriteLine(item.Title); } } catch (Exception ex) { if (trans != null) { trans.Rollback(); } throw ex; } finally { trans.Dispose(); } } } }
执行结果:
如果数据不需要做修改和删除操作,仅仅是查询可以加上AsNoTracking,提高查询效率。
var vList = dbContext.News.Where(n => n.Id > 10).AsNoTracking().ToList();
转载地址:http://uijzb.baihongyu.com/