最开始的对象查询是用foreach来遍历输出
List<string
> fruits = new List<string>() { "苹果", "香蕉", "西瓜", "香瓜" };//{}对象集合初始化器,没有构造函数的初始化
Console.Write("请输入水果名:");
string str = Console.ReadLine();
foreach (var itme in fruits)
if (itme.Contains(str)) Console.WriteLine(itme);//Contains模糊查询条件
Linq查询原理:其实就是把查询条件进行封装成一些个扩展方法
Linq to object(数组跟集合)查询的是内存数据
Linq to sql (数据库)查询数据库数据
Linq to XML 查询xml文件用的
其实他们条件语法都一样,只是查询对象不同。
这里添加实体类做数据演示:linq to obj 做内存集合数据源
//给实体类存放一些初始值
List<Students> plist = new List<Students>() {
new Students() { Id = 1, Name = "a冰箱", Price = 2300, Brand = "西门子1", Sell = "B202",lover = new List<string>(){ "苹果", "香蕉", "西瓜" }},
new Students() { Id = 2, Name = "b冰箱", Price = 2400, Brand = "西门子2", Sell = "B303",lover = new List<string>(){ "木瓜", "芒果", "地瓜" }},
new Students() { Id = 3, Name = "c电视", Price = 2500, Brand = "西门子3", Sell = "B404",lover = new List<string>(){ "橘子", "柿子", "水果" }},
new Students() { Id = 4, Name = "d电视", Price = 2600, Brand = "西门子4", Sell = "B505",lover = new List<string>(){ "柚子", "香瓜", "西瓜" }}
void Show(List<Students> fruits)
foreach (var itme in fruits)
Console.WriteLine("编号:{0},商品名称:{1},商品价格:{2},商品品牌:{3},商品型号:{4}", itme.Id, itme.Name, itme.Price, itme.Brand, itme.Sell);
Show(plist);
/// <summary>
/// 实体类Model:作用于数据传递。
/// </summary>
public class Students
public Nullable<int> Id { get; set; } //Nullable<int>表示值类型也可以赋空值 int? id = null 就不会不错 一般来说int是没有空值 string有
public string Name { get; set; }
public int? Price { get; set; } // int? 是 Nullable<int> 的简化 ,用于值类型,表示可以为空null
public string Brand { get; set; }
public string Sell { get; set; }
public List<string> lover { get; set; }
自定义linq:if语句的条件判断一步步演变过来的
var list = plist.MyWhere(x => x.Id == 1 && x.Name == "a冰箱").ToList();//自定义linq查询条件的筛选方法
Show(list);
public static class LinqExtend //扩展方法只能定义在静态类中,给IEnumerable接口添加MyWhere方法,IEnumerable是可迭代枚举型,可以被foreach遍历
public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> ts, Func<T, bool> func) //委托返回布尔值,Invoke执行委托,写不写都可以:func(item)也可以执行。
List<T> list = new List<T>();
foreach (var item in ts)
if (func.Invoke(item)) list.Add(item);
return list;
系统linq:上面是Where方法内部大概语法。where是官方给的扩展方法。
var list = plist.Where(x => x.Id == 1 && x.Name == "a冰箱").ToList();//系统linq的扩展方法where查询条件
Show(list);
Linq语法官方给了两种写法:IEnumerable<T>接口的【扩展方法式】和【表达式】
linq表达式:这种方式最后生成代码和扩展方法式是一样的,最后代码翻译为方法式。所以建议使用扩展方法式。表达式语法:Select * from 数据源(表明)
var list = (from f in plist //数据源:也就是一个集合,遍历list
orderby f.Id descending //orderby排序(默认的升序) 跟 descending降序 (ascending升序)
where f.Name.Contains("冰箱") //Contains模糊查询
select f).ToList();//显示结果返回给reus变量,可查询字段(如果查询全部直接放变量名) 就像f是变量名 数据库字段 f.id 这种得到字段的所有值
Show(list);
select方法是投影,
var list = plist.Select(s => new { id = s.Id, name = s.Name }).ToList();//var s = new {} 匿名类,匿名对象。
foreach (var itme in list) Console.WriteLine(itme.id + ":" + itme.name);
from复合子句:多集合查询,查询条件是一个集合,数据源也是一个集合
string lovers = "苹果,香瓜";
List<string> loverlist = lovers.Split(',').ToList();//根据用户输入爱好 ,号来划分字符串
var list = from f in plist//数据源也是一个集合:使用复合子句把数据源集合变成一个一个的字符串
from loveritem in f.lover
where loverlist.Contains(loveritem) //查询条件是一个集合
select f;
Show(list.ToList());//显示数据的方法
复合子句Select查询单个字段
string lovers = "苹果,香瓜";
List<string> loverlist = lovers.Split(',').ToList();//根据用户输入 ,号来划分字符串
var list = from f in plist//数据源
from loveritem in f.lover
where loverlist.Contains(loveritem)
select f.Name; //复合字句查询,单个字段不是全部字段
List<string> unamelist = list.ToList();
foreach (var item in unamelist)
Console.WriteLine(item);
复合子句Select查询多个字段
string lovers = "苹果,香瓜";
List<string> loverlist = lovers.Split(',').ToList();//根据用户输入 ,号来划分字符串
var list = from f in plist//数据源
from loveritem in f.lover
where loverlist.Contains(loveritem)
select new
{ //复合子句查询,多字段
a = f.Id,
b = f.Name,
c = f.Price
foreach (var item in list)
Console.WriteLine("编号:{0},产品名:{1},价格:{2}", item.a, item.b, item.c);
join多表连接查询:建议使用表达式
var table2 = new[] { new { id = 1, name = "张三" }, new { id = 2, name = "李四" } };//定义第二张表,初始化两条数据
var list = from p in plist //连几个表就加几个join往后写即可
join t in table2 on p.Id equals t.id //需要用equals表示等于,这里不能向数据库语法一样用==号。
select new { aa = p.Id, bb = p.Name, cc = t.name };//select在数据库里就是查询对象的一个临时表集合。
foreach (var itme in list)
Console.WriteLine($"编号:{itme.aa},名称:{itme.bb},姓名:{itme.cc}");
join多表查询的扩展方法式,如果是3张表以上就不方便
var table2 = new[] { new { id = 1, name = "张三" }, new { id = 2, name = "李四" } };//定义第二张表,初始化两条数据
var list = plist.Join(table2, p => p.Id, t => t.id,//参数1:连接的表,参数2:委托返回表1id,参数2:委托返回表2id,相当于连接条件:p.id ==t.id
(p, t) => new { aa = p.Id, bb = p.Name, cc = t.name });//参数3:相当于select,委托两个参数返回一个临时表集合
foreach (var itme in list)
Console.WriteLine($"编号:{itme.aa},名称:{itme.bb},姓名:{itme.cc}");
linq查询的其他扩展方法
var list = plist.Skip(5)//跳过5条数据,分页会用到
.Take(3)//显示前面3条数据,.Concat(plist.Take(5));可以返回行数,查询到的数据条数
.OrderByDescending(x => x.Id) //降序,OrderBy是升序
.Where(s => s.Name.Contains("冰箱"))//Contains包含,模糊查询用,FirstOrDefault也一样放where条件类名才能加参数。
.FirstOrDefault();//返回第一个查询到的,没有就返回null,而First查不到就报错,这个不是模糊查询,数据要一致匹配。
linq to sql:数据库查询 IQueryable接口的AsQueryable方法
连接测试数据库:这里通过ADO.net创建实体数据模型的一个上下文映射类。ADO连接方式已经被淘汰不用研究,这里只是用来了解linq to sql语法
create database OA
use OA
create table userinfo
id int primary key identity(1,1),
name nvarchar(20),
sex char(5),
age int,
insert into userinfo values('张三','男',19)
insert into userinfo values('麻花','女',17)
insert into userinfo values('小二','男',20)
select * from userinfo
OAEntities OA = new OAEntities();//数据库对象,用ado.net实体数据模型创建出来的上下文映射对象。就当测试数据库用
//linq to sql 数据库查询 语法:数据库对象.表名.AsQueryable方法,主要查询数据库默认都是AsQueryable(),使用可以省略不写
var list = OA.userinfo.Where(s=>s.id>0).Where(s=>s.age>16).ToList();
foreach (var item in list)Console.WriteLine(item.id);//遍历输出显示
IQueryable接口其实也是继承了IEnumerable可迭代枚举型。只是IQueryable增加了一些功能,用于查询数据库。
IQueryable:是在数据库了处理好条件查询,在拿出来遍历。---AsQueryable() 方法:对象是数据库,默认的可以不写。
IEnumerable:则把数据全部拿出来到内存里做筛选,如果数据多这样就会很占用空间。---AsEnumerable() 方法:对象是内存中【类,字符串,数组等等】。默认的所以也没写出来。
如果加方法就变成转换,如:其实数据库也可以用AsEnumerable方法,因为他本来IQueryable就继承IEnumerable。只是IEnumerable只能筛选内存数据。所以就有了IQueryable。
OAEntities OA = new OAEntities();
//语法:数据库对象.表名.AsQueryable方法,主要查询数据库默认都是AsQueryable(),省略不写
var list = OA.userinfo.AsEnumerable().Where(s=>s.id>0).Where(s=>s.age>16).ToList();//改为AsEnumerable内存筛选查看区别。
foreach (var item in list)Console.WriteLine(item.id);//遍历输出显示
可以运行SQL跟踪工具查看这两个区别

很显然AsQueryable把条件都传到数据库了去执行筛选。而AsEnumerable把数据全部拿出来在去内存里做筛选。