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处理表关联,可以参考:https://www.cnblogs.com/xinwang/p/6145837.html
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);
List<News> newList = dbContext.Database.SqlQuery<News>(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();