查询用例
1、简单示例
查所有、查单 条、聚合函数、是否存在 、模糊查询等例子
var getAll = db.Queryable().ToList();//查询所有
var top10= db.Queryable().Take(10).ToList();//查询前10
var getFirst = db.Queryable().First(it=>it.Id1);//查询单条
var getAllNoLock = db.Queryable().With(SqlWith.NoLock).ToList();//SqlServer里面的withnolock
var getByPrimaryKey = db.Queryable().InSingle(2);//根据主键查询
var sum = db.Queryable().Sum(it=>it.Id);//查询总和
var isAny = db.Queryable().Where(it=>it.Id-1).Any();//是否存在
var isAny2 = db.Queryable().Any(it => it.Id == -1);
var getListByRename = db.Queryable().AS(“Student”).ToList();
var getByWhere = db.Queryable().Where(it => it.Id == 1 || it.Name == “a”).ToList();
var list= db.Queryable().AS(“student2019”).ToList();//select * from student2019
var list2 = db.Queryable().Where(it =>it.Name.Contains(“jack”)).ToList();//模糊查询 name like ‘%’+@name+’%’
2、 分组查询
只有在聚合对象需要筛选的时候才会用到Having,一般分组查询用不到可以去掉
var list = db.Queryable()
.GroupBy(it => new { it.Id, it.Name })
.Having(it => SqlFunc.AggregateAvg(it.Id) > 0)//不是聚合函数用Where就可以了
.Select(it => new { idAvg = SqlFunc.AggregateAvg(it.Id), name = it.Name })
.ToList();
//SELECT AVG([Id]) AS[idAvg], [Name] AS[name] FROM[Student] GROUP BY[Name],[Id] HAVING(AVG([Id]) > 0 )
根据时间分组,不计时分秒,只按日期分组
var getOrderBy = db.Queryable().Select(it=>new {
Id=it.Id,
Name=it.Name,
CreateTime=it.CreateTime.Date//只取日期
})
.MergeTable()//将查询结果转成一个表
.GroupBy(it=>it.CreateTime)
.Select(it=>new { id =SqlFunc.AggregateMax(it.Id),crate=it.CreateTime })
.ToList();
按一个字段分组取第N条(不是所有数据库都支持)
db.Queryable().PartitionBy(it=>it.Name).Take(1).ToList()
3、 去重查询
var list = db.Queryable().Distinct().Select(it => new { it.Name }).ToList();
SELECT DISTINCT [Name] AS [Name] FROM [STudent]
4、分页
//同步分页
int pageIndex = 1;
int pageSize = 20;
int totalCount=0;
var page = db.Queryable().ToPageList(pageIndex, pageSize, ref totalCount);
//异步分页
RefAsync total = 0;
Db.Queryable().ToPageListAsync(pageIndex, pageSize, total);
//分页Sql
//SELECT * FROM
//(SELECT [ID],[SchoolId],[Name],[CreateTime],ROW_NUMBER()
// OVER(ORDER BY GetDate())AS RowIndex FROM [STudent]) T
//WHERE RowIndex BETWEEN 1 AND 20
5、并集查询
var q1 = db.Queryable().Select(it=>new Model{ name=it.Name });
var q2 = db.Queryable().Select(it => new Model { name = it.Name });
var list = db.UnionAll(q1, q2).ToList();
SELECT * FROM (SELECT [Name] AS [name] FROM [STudent] UNION ALL
SELECT [Name] AS [name] FROM [School] ) unionTable
6、使用Sql函数
var getByFuns = db.Queryable().Where(it => SqlFunc.Between(it.Id,1,2)).ToList();
7、排序
//表达示排序
var list = db.Queryable
.OrderBy(st=>st.Id)
.OrderBy((st,sc)=>sc.Id,OrderByType.Desc)
.Select().ToList();
//表达示连写
var list = db.Queryable
.OrderBy(st=>new {st.Id,sc.Id})
.Select().ToList();
//动态排序
var list = db.Queryable
.OrderBy("st.id asc,sc.Id desc ") //单表不需要加st.这种前缀
.Select().ToList();
//上面多表查询的时候动态排序需要加别名 ,如何去掉别名呢代码如下
var pageJoin =db.Queryable
.Select((st, sc) => new {
id = st.Id,
name = sc.Name
})
.MergeTable()//将查询结果集变成表 MergeTable
.Where(it => it.id == 1).OrderBy(“name asc”).ToList();//对表MergeTable进行排序
8、没有实体的查询
var list = db.Queryable().AS("order ").Where(“id=id”, new { id = 1 }).ToList();//没实体一样用
var list2 = db.Queryable(“o”).AS(“order”)
.AddJoinInfo(“OrderDetail”, “i”, “o.id=i.OrderId”)
.Where(“id=id”, new { id = 1 })
.Select(“o.*”).ToList();
9、异步
异步就是在原有的方法后面加Async例如,ToList改成ToListAsync
异步分页需要注意传参有点不同代码如下
var task1=db.Queryable().FirstAsync();
var task2 = db.Queryable().Where(it=>it.Id==1).ToListAsync();
//分页需要特别注意用法
RefAsync total = 0;
Db.Queryable().ToPageListAsync(1, 2, total);
10、分组取第一条,部分数据库支持
var list3 = db.Queryable()
.PartitionBy(it => new { it.Id, it.Name }).Take(1).ToList();
11、操作In(1,2,3)
int [] allIds=new int[]{1,2,3};
db.Queryable().Where(it => allIds.Contains(it.OrderId)).ToList()
//sql select * from OrderItem where odrderid in (1,3,3)
12、操作IN 并且是2个字段逻辑
var ids = new int[] { 1, 3, 8, 5 };
Expressionable exp = new Expressionable();
foreach (var item in ids)
{
exp.Or(it => it.Id == item && it.Name.Contains(item.ToString()));
}
var list= db.Queryable().Where(exp.ToExpression()).ToList();
//SELECT [Id],[Name],[Price],[CreateTime],[CustomId] FROM [Order] WHERE
//((((( [Id] = @Id0 ) AND ([Name] like ‘%’+ CAST(@MethodConst1 AS NVARCHAR(MAX))+’%’) )
//OR (( [Id] = @Id2 ) AND ([Name] like ‘%’+ CAST(@MethodConst3 AS NVARCHAR(MAX))+’%’) ))
//OR (( [Id] = @Id4 ) AND ([Name] like ‘%’+ CAST(@MethodConst5 AS NVARCHAR(MAX))+’%’) ))
//OR (( [Id] = @Id6 ) AND ([Name] like ‘%’+ CAST(@MethodConst7 AS NVARCHAR(MAX))+’%’) ))
//@Id0:1,@MethodConst1:1,@Id2:3,@MethodConst3:3,@Id4:8,@MethodConst5:8,@Id6:5,@MethodConst7:5
13、二次查询
var getAll = db.Queryable()
.Select(it => new Order
{
Id = it.Id * 2,
Name = it.Name
})
.MergeTable()//将上面的操作变成一个表 mergetable
.GroupBy(it => it.Id)//对表mergetable进行分组
.Select(it =>new{ id=it.Id }).ToList();//查询mergetable表里面的字段
SELECT Id
FROM
(SELECT ( Id
* @Id0 ) AS Id
, Name
AS Name
FROM Order
) MergeTable
GROUP BY Id
参数 @Id0:2
联表查询
1、三表查询联接查询
实现 a.*, b.name as bname
上面是用了自动填充,下面我们用手动快速填充的方式实现
var list = db.Queryable
.Select((o,i,c)=> new ViewOrder
{
Id=SqlFunc.GetSelfAndAutoFill(o.Id),// o.*
CustomName=c.Name //[c].[Name] AS [CustomName]
})
.ToList();
// SELECT
// o.*,
// [c].[Name] AS [CustomName]
// FROM [Order] o ,
// [OrderDetail] i ,
// [Custom] c
// WHERE(([o].[Id]=[i].[OrderId])AND([c].[Id]=[o].[CustomId]))
Left Join
var oneClass = db.Queryable
JoinType.Left, o.Id == i.OrderId,
JoinType.Left, o.CustomId == c.Id
))
.Select((o,i,c)=> new ViewOrder
{
Id=SqlFunc.GetSelfAndAutoFill(o.Id),// o.*
CustomName=c.Name //[c].[Name] AS [CustomName]
}).ToList()
Join中Where用法
var oneClass = db.Queryable
JoinType.Left, o.Id == i.OrderId,
JoinType.Left, o.CustomId == c.Id
))
.Where(o=>o.id1) //只用到o这样写就行
.Where((o,i)=>i.xx1) //如果用到i需要这么写
.Select((o,i,c)=> new ViewOrder
{
Id=SqlFunc.GetSelfAndAutoFill(o.Id),// o.*
CustomName=c.Name //[c].[Name] AS [CustomName]
}).ToList()
按规则自动填充
需要注意的是 Select用的是自动填充这样使用方便,高并发的地方还是写成上面那种方式
public class ViewModelStudent : Student
{
public string SchoolName{get;set;}// 类名 + 属性名
}
var list = db.Queryable
JoinType.Left,st.SchoolIdsc.Id,//可以用&&实现 on 条件 and
JoinType.Left,st.Namedi.String
))
//.Where((st,sc)=>sc.id>0) 多表条件用法
.Select().ToList();
//SELECT
//sc.[Name] AS [SchoolName],–自动生成 SchoolName
//st.[ID] AS [Id],st.[SchoolId] AS [SchoolId],
//st.[Name] AS [Name],st.[CreateTime] AS [CreateTime]
//FROM [STudent] st
//Left JOIN [School] sc ON ( [st].[SchoolId] = [sc].[Id] )
//Left JOIN [DataTestInfo] di ON ( [st].[Name] = [di].[String] )
2、两个queryable查询
把一个单 表查询和一个多表查询在进行了一次Join操作
var query1 = db.Queryable
JoinType.Left,st.SchoolId==sc.Id
))
.Where(st => st.Name == “jack”);
var query2 = db.Queryable();
db.Queryable(query1, query2, (p1, p2) => p1.Id == p2.Int1).Select().ToList();
//SELECT * FROM
// (SELECT [st].[ID],[st].[SchoolId],[st].[Name],[st].[CreateTime]
// FROM [STudent] st
// Left JOIN [School] sc ON ([st].[SchoolId]=[sc].[Id] )
// WHERE ( [st].[Name] = @Name0Join0 )) p1
//
// Inner JOIN
// (SELECT [Int1],[Int2],[String],[Decimal1],[Decimal2],
// [Datetime1],[Datetime2],[Image1],[Image2],
// [Guid1],[Guid2],[Money1],[Money2],[Varbinary1],
// [Varbinary2],[Float1],[Float2] FROM [DataTestInfo] )p2
// ON ( [p1].[ID] = [p2].[Int1] )
3、简单联表
代码:
var list = db.Queryable
.Select()
.ToList();
sql:
SELECT c.[Name] AS [CustomName],
o.[Id] AS [Id],o.[Name] AS [Name],
o.[Price] AS [Price],
o.[CreateTime] AS [CreateTime],
o.[CustomId] AS [CustomId] FROM [Order] o ,[OrderDetail] i ,[Custom] c
WHERE (( [o].[Id] = [i].[OrderId] ) AND ( [c].[Id] = [o].[CustomId] ))
4、子查询
例子1:
var list = db.Queryable().Take(10).Select(it => new
{
customName=SqlFunc.Subqueryable().Where(s=>it.CustomId==s.Id).Select(s=>s.Name),
customName2 = SqlFunc.Subqueryable().Where(“it.CustomId = id”).Where(s => true).Select(s => s.Name)
//count = SqlFunc.Subqueryable().Where(“it.CustomId = id”).Where(s => true).Count()
//sum= SqlFunc.Subqueryable().Where(“it.CustomId = id”).Where(s => true).Sum(it=>it.xx)
}).ToList();
SELECT * FROM ( SELECT (SELECT TOP 1 [Name] FROM [Custom] WHERE it.CustomId=id) AS [customName] ,
(SELECT TOP 1 [Name] FROM [Custom] WHERE ( 1 = 1 ) AND it.CustomId=id)AS[customName2] ,
ROW_NUMBER() OVER( ORDER BY GetDate() ) AS RowIndex FROM [Order] it )
T WHERE RowIndex BETWEEN 1 AND 10
例子2:
如果NOT逻辑用 !SqlFunc.Subqueryable
var list2 = db.Queryable().Where(it => SqlFunc.Subqueryable().Where(i => i.OrderId == it.Id).Any()).ToList();
SELECT [Id],[Name],[Price],[CreateTime],[CustomId] FROM [Order] it
WHERE (EXISTS ( SELECT * FROM [OrderDetail] WHERE ( [OrderId] = [it].[Id] ) ))
–等同于 WHERE it.id in(SELECT OrderId from orderdetail )
5、将多表转成一表,实现动态查询
var pageJoin = db.Queryable
{
JoinType.Left,st.SchoolIdsc.Id
})
.Select((st,sc) => new
{
id = st.Id,
name = sc.Name
})
.MergeTable()
.Where(it=>it.id1).OrderBy(“name asc”).ToList();//别名不限
SELECT * FROM
(SELECT
[st].[Id] AS [id] , [sc].[Name] AS [name]
FROM [Student] st Left
JOIN [School] sc ON ( [st].[CustomId] = [sc].[Id] ) ) MergeTable--将结果变成一个表
WHERE ( [id] = @id0 )ORDER BY name asc
6、将多表转成一表后,在查询
var pageJoin = db.Queryable
{
JoinType.Left,st.CustomId==sc.Id
})
.Select((st, sc) => new
{
id = st.Id,
name = sc.Name
})
.MergeTable()
.GroupBy(it=>it.id).GroupBy(it=>it.name)
.Select(it=>new { it.id ,name=it.name+it.id.ToString() }).ToList();
SELECT [id] AS [id] ,
([name] + CAST([id] AS NVARCHAR(MAX))) AS [name]
FROM
(SELECT [st].[Id] AS [id] , [sc].[Name] AS [name] FROM [Order] st
Left JOIN [Custom] sc ON ( [st].[CustomId] = [sc].[Id] )
) MergeTable GROUP BY [id],[name]
查询结果
返回List
List list = db.Queryable().ToList();
返回第一个实体
Student item = db.Queryable().First(it=>it.Id==1);
返回DataTable
DataTable dataTable = db.Queryable().Select(it => it.Id).ToDataTable();
返回Json
var json = db.Queryable().ToJson();
返回数组
List listInt=db.Queryable().Select(it => it.Id).ToList();
返回匿名对象
var dynamic = db.Queryable().Select().ToList();
返回到新类
var viewModel = db.Queryable
JoinType.Left, st.SchoolId == sc.Id,
JoinType.Left, st.Name == di.String
))
.Select().ToList();
多表返回匿名对象
var newDynamic = db.Queryable
JoinType.Left, st.SchoolId == sc.Id,
JoinType.Left, st.Name == di.String
)) .Select((st,sc,di)=>new { name=st.Name,scid=sc.Id }).ToList();
手动返回到新类
var newClass= db.Queryable
JoinType.Left, st.SchoolId == sc.Id,
JoinType.Left, st.Name == di.String
)) .Select((st,sc,di)=>new ClassName{ name=st.Name,scid=sc.Id }).ToList();
多表查一表
var oneClass = db.Queryable
JoinType.Left, o.Id == i.OrderId,
JoinType.Left, o.CustomId == c.Id
))
.Select((o, i, c) => c).ToList();
多表返回2表
var twoClass = db.Queryable
JoinType.Left, o.Id == i.OrderId,
JoinType.Left, o.CustomId == c.Id
))
.Select((o, i, c) => new { o,i}).ToList()
返回字典
//表达式返回字典
Dictionary
//动态Sql返回字典
Dictionary
.Select
.ToList().ToDictionary(it=>it.Key,it=>it.Value);
返回字典集合
List
ORM解析特殊函数
当我们使用Select时候有一个字段用到了特殊的C#函数解析不了,我们可以用Mapper单独对这个字段进行处理,
原理:是Select是用来生成Sql,Mapper是对ToList后的结果进行的转换,所以支持任何C#函数
var newClass = db.Queryable
JoinType.Left, o.Id == i.OrderId,
JoinType.Left, o.CustomId == c.Id
))
.Select((o, i, c) => new ViewOrder {
Name =o.Name,
CustomName=c.Name,
Id=it.Id//暂时不处理
})
.Mapper(it=> {
it.Id = Util.GetNo(it.Id) ; //这里处理
Mapper处理匿名对象需要这么写,需要加上(daynamic)
db.Queryable
JoinType.Left, o.Id == i.OrderId,
JoinType.Left, o.CustomId == c.Id
))
.Select((o, i, c) =>
(dynamic) new { orderName = o.Name, cusName=c.Name }).Mapper(it=> { it.orderName = “_”+it.orderName; }).ToList();
更多Mapper用法: http://www.codeisbug.com/Home/Doc?typeId=1188
双查询结果用法
当我们需要在select后在外面在包一层select,代码如下
var getAll = db.Queryable()
.Select(it => new Order
{
Id = it.Id * 2,
Name = it.Name
})
.MergeTable()//将上面的操作变成一个表 mergetable
.GroupBy(it => it.Id)//对表mergetable进行分组
.Select(it =>new{ id=it.Id }).ToList();//查询mergetable表里面的字段
SELECT Id
FROM
(SELECT ( Id
* @Id0 ) AS Id
, Name
AS Name
FROM Order
) MergeTable
GROUP BY Id
参数 @Id0:2
树型查询
var tree = db.Queryable().ToTree(it=>it.Child,it=>it.ParentId,0); //第三个参数为0代表 parent为0是第一级
//实体
public class Tree
{
[SqlSugar.SugarColumn(IsPrimaryKey =true)]
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
[SqlSugar.SugarColumn(IsIgnore = true)]
public List Child { get; set; }
}
查询条件
1、普通表达式查询
//id=@id
var list=db.Queryable().Where(it => it.Id == id).ToList();
var list2=db.Queryable().WhereIF(id>0,it => it.Id == id).ToList();// 如果id>0 添加条件 id=@id 否则查询所有
//id=@id or name like ‘%’+@name+’%’
var list2 = db.Queryable().Where(it => it.Id == id||it.Name.Contains(“jack”)).ToList();
2、根据SQL查询
//id=@id
var list=db.Queryable().Where(“id=@id”,new { id=1}).ToList();
//id=@id or name like ‘%’+@name+’%’
var list2 = db.Queryable().Where("id=@id or name like ‘%’+@name+’%’ ",new { id=1,name=“jack”}).ToList();
3、动态组装查询
//简单用例
var conModels = new List();
conModels.Add(new ConditionalModel{ FieldName = “id”, ConditionalType = ConditionalType.Equal, FieldValue = “1”});
var student = db.Queryable().Where(conModels).ToList();
//复杂用例
List conModels = new List();
conModels.Add(new ConditionalModel{ FieldName = “id”, ConditionalType = ConditionalType.Equal,FieldValue=“1”});
conModels.Add(new ConditionalModel{ FieldName = “Student.id”,ConditionalType = ConditionalType.Equal, FieldValue=“1”});
conModels.Add(new ConditionalModel{ FieldName = “id”, ConditionalType = ConditionalType.Like, FieldValue = “1” });
conModels.Add(new ConditionalModel{ FieldName = “id”, ConditionalType = ConditionalType.IsNullOrEmpty });
//id in (‘一’,‘二’,‘三’) FieldValue不能存在单引号,正确代码如下
conModels.Add(new ConditionalModel{ FieldName = “id”, ConditionalType = ConditionalType.In,FieldValue = “一,二,三”});
//not in
conModels.Add(new ConditionalModel{ FieldName = “id”, ConditionalType = ConditionalType.NotIn,FieldValue = “1,2,3”});
conModels.Add(new ConditionalModel{ FieldName = “id”, ConditionalType = ConditionalType.NoEqual,FieldValue=“1,2,3”});
conModels.Add(new ConditionalModel{ FieldName = “id”, ConditionalType = ConditionalType.IsNot,FieldValue=null });
conModels.Add(new ConditionalCollections()
{
ConditionalList = new List
// (id=1 or id=2 and id=1)
{
new KeyValuePair
{ FieldName = “id”, ConditionalType = ConditionalType.Equal, FieldValue = “1” }),
new KeyValuePair
{ FieldName = “id”, ConditionalType = ConditionalType.Equal, FieldValue = “2” }),
new KeyValuePair
{ FieldName = “id”, ConditionalType = ConditionalType.Equal, FieldValue = “2” })
}
});
var student = db.Queryable().Where(conModels).ToList();
4、条件拼接查询
var query = db.Queryable().Where(it=>it.Id==1);
if(条件)
query.Where(it => it.Name == “jack”);
if(条件)
query.Where(it => it.Id==1);
int count=query.Clone().Count();//当query用于2个地方的时候一定要加Clone这点和EF有本质区别
var list=query.Clone.ToList();
5、动态拼表达式查询 ,拼拉姆达
var exp= Expressionable.Create()
.And(it=>it.Id==1)
.Or(it =>it.Name.Contains(“jack”)).ToExpression();
var list=db.Queryable().Where(exp).ToList();
6、链式条件查询
var query = db.Queryable()
.WhereIF(!string.IsNullOrEmpty(name), it => it.Name.Contains(name))
.WhereIF(id>0, it => it.Id==id).ToList();
多级查询
1、一对一查询
根据子对象Order主键与主表中的OrderId进行关联
public class OrderItem {
[SugarColumn(IsPrimaryKey =true ,IsIdentity =true)]
public int ItemId { get; set; }
public string ItemCode { get; set; }
public decimal Pirce { get; set; }
public int OrderId { get; set; }
[SugarColumn(IsIgnore =true)]
public Order Order{ get; set; }
}
public class Order {
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
[SugarColumn(IsIgnore = true)]
public List Items { get; set; }
}
var list= db.Queryable().Mapper(it => it.Order, it => it.OrderId).ToList();
2、一对多查询
根据子对象items中的OrderId与主表的主键进行关联
public class Order
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
[SugarColumn(IsIgnore = true)]
public List Items { get; set; }
}
public class OrderItem {
[SugarColumn(IsPrimaryKey =true ,IsIdentity =true)]
public int ItemId { get; set; }
public string ItemCode { get; set; }
public decimal Pirce { get; set; }
public int OrderId { get; set; }
[SugarColumn(IsIgnore =true)]
public Order Order{ get; set; }
}
var list= db.Queryable().Mapper(it => it.Items, it => it.Items.First().OrderId).ToList();
3、 多对多查询
public class ABMapping
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int AId { get; set; }
public int BId { get; set; }
[SugarColumn(IsIgnore = true)]
public A A { get; set; }
[SugarColumn(IsIgnore = true)]
public B B { get; set; }
}
public class A {
[SugarColumn(IsPrimaryKey =true ,IsIdentity =true)]
public int Id { get; set; }
public string Name { get; set; }
}
public class B
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
}
var list= db.Queryable()
.Mapper(it => it.A,it=>it.AId)
.Mapper(it => it.B, it => it.BId).ToList();
4、 相同字段名映射
子表对象=子表对象.where(it=>it.OrgId==主表对象中的.OrgId)
public class A {
[SugarColumn(IsPrimaryKey =true ,IsIdentity =true)]
public int Id { get; set; }
public string Name { get; set; }
public string OrgId { get; set; }
[SugarColumn(IsIgnore =true)]
public B B { get; set; }
}
public class B
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
public string OrgId { get; set; }
}
var list= db.Queryable().Mapper(it => it.B,it=>it.OrgId).ToList();
5、无规律映射
1对1和1对多都是通过一个字段和主键进行的映射,如果没有主键呢,这个时候就需要指定2个字段进行映射
public class Tree
{
[SqlSugar.SugarColumn(IsPrimaryKey =true)]
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
[SqlSugar.SugarColumn(IsIgnore = true)]
public Tree Parent { get; set; }
[SqlSugar.SugarColumn(IsIgnore = true)]
public List Child { get; set; }
}
var list=db.Queryable()
//parent=(select * from parent where id=it.parentid)
// 子表对象 = 指定主表映射字段 指定子表映射字段
.Mapper(it=>it.Parent,it=>it.ParentId, it=>it.Parent.Id)
//Child=(select * from parent where ParentId=it.id)
// 子表对象 = 指定主表映射字段 指定子表映射字段
.Mapper(it => it.Child, it => it.Id, it => it.Parent.ParentId)
.ToList();
6、 自定义查询
当我们需要灵活进行多级查询时我们可以这么写
List list = db.Queryable().Mapper((order,cache)=> {
orderItem.Items = db.Queryable().Where(it => it.OrderId == order.Id).ToList();
}).ToList();//缺点性能差会引起循环
将上面的代码进行性能优化 ,功能一模一样 ,代码如下:
List list = db.Queryable().Mapper((order,cache)=> {
//cache.get 内的方法永远只执行一次
List allOrderItems = cache.Get(ol => //ol的值等于db.queryable().tolist()
{
//查询出所有的OrderId集合
var allOrderIds = ol.Select(x => x.Id).ToList();
//查询出N个OrderId所对应的OrderItem
return db.Queryable().In(it => it.OrderId, allOrderIds).ToList();
});
//allOrderItems已经查询出N个OrderId所需要的Iitem,我们在从allOrderItems取出我要的
orderItem.Items = allOrderItems.Where(it => it.OrderId == order.Id).ToList();
}).ToList();
实体
public class Order
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime CreateTime { get; set; }
[SugarColumn(IsNullable =true)]
public int CustomId { get; set; }
[SugarColumn(IsIgnore = true)]
public List Items { get; set; }
}
7、N级查询,意思就是嵌套了N层一次性全部查询出来
List
.Where(s => s.FBIZDATE == fBizDate && s.FSALERID == FsalerID)
//第二层 可以偷懒,用一对多 一对一 等方式 进行查询
.Mapper(s => s.LadEntryList, s => s.FID)
//第三只能自定义查询
.Mapper((s, cache) => {
//可以断点调试 ,s.LadEntiryList 在第二层查询中已经赋过值了
foreach(var t in s.LadEntryList)
{
t.MATERIAL=Context.Queryable()
.Where(o => o.FMATERIALID == t.FMATERIALID)
.First();//给第三层赋值
}
});
})
//.Mapper((s,acche)) 可以实现第四层查询
.ToList();
//上面的写法查第一层和第二层不管多少条记录只会产生2条Sql,但是查第三层的时候会产生多条查询
//了解Mapper原理之后,对性能要求高的页面,我们可以用 cache.get进行优化(示例6和示例8 )
8、多对多中间表查询运用自定义Mapper Cache实现
var list = db.Queryable<用户>()
.Mapper((result, cache) =>
{
var allMps = cache.Get>(l =>
{
//查出N个用户所需要的中间表
var cres = db.Queryable<用户职位中间表>()
.Mapper(y => y.职位, y => y.职位id)
.In(it => it.用户id, l.Select(it => it.Id).ToArray())
.ToList();
return cres;
});
//获取当前用户所需要的中间表
result.职位 = allMps
.Where(it => it.用户id == result.Id)
.Select(it => it.职位)
.ToList();
}).ToList();
public class 用户
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
[SugarColumn(IsIgnore = true)]
public List<职位> 职位 { get; set; }
}
public class 用户职位中间表
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
public int 用户id { get; set; }
public int 职位id { get; set; }
[SugarColumn(IsIgnore = true)]
public 用户 用户 { get; set; }
[SugarColumn(IsIgnore = true)]
public 职位 职位 { get; set; }
}
public class 职位
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int ID { get; set; }
public string ItemCode { get; set; }
public decimal Pirce { get; set; }
}
查询函数
我们可以使用SqlFunc这个类调用Sql函数,用法如下:
db.Queryable().Where(it => SqlFunc.ToLower(it.Name) == SqlFunc.ToLower(“JACK”)).ToList();
支持的C#函数:
.ToString .Contains .Length
.ToLower .ToUpper .ToSubstring
.Equals .HasValue .Replace
.EndsWith .StartsWith .Trim
.HasValue .Value .AddDay .Date
和常用的Convert.ToInt32等
SqlFunc函数:
三元判段 ,相当于 it.id==1?1:2
SqlFunc.IIF(it.Id == 1, 1, 2)
if else 4.6.0.1
SqlFunc.IF(st.Id > 1)
.Return(st.Id)
.ElseIF(st.Id == 1)
.Return(st.SchoolId).End(st.Id)
IsNulll4.6.0.1
SqlFunc.IsNull(it.Id, 0)//如果是null则是0
获取数据库时间4.6.0.1
SqlFunc.GetDate();
字符串相加函数,除了SqlServer外很多库对+不友好可以使用
SqlFunc.MergeString
判段是NULL或者空
SqlFunc.IsNullOrEmpty(object thisValue)
判段不是NULL并且不是空
SqlFunc.HasValue(object thisValue)
按位与 按位或
SqlFunc.BitwiseAnd &
SqlFunc.BitwiseInclusiveOR |
判段大于0并且不等于NULL
SqlFunc.HasNumber(object thisValue)
转小写
SqlFunc.ToLower(object thisValue)
转大写
SqlFunc.ToUpper(object thisValue)
去前后空格
SqlFunc.Trim(object thisValue)
模糊查询 like %@p%
SqlFunc.Contains(string thisValue, string parameterValue)
也可以使用 .Where(it=>it.Name.Contains(“a”));
In操作 thisValue={1,2,3} 生成的Sql就是 paramterValie in (1,2,3)
SqlFunc.ContainsArray(object[] thisValue, string parameterValue)
也可以使用 .Where(it=>数组变量.Contains(it.Id));
Not In 操作
.Where(it=>!Array.Contains(it.Id));
模糊查询 like @p%
SqlFunc.StartsWith(object thisValue, string parameterValue)
模糊查询 like %@p
SqlFunc.EndsWith(object thisValue, string parameterValue)
等于
SqlFunc.Equals(object thisValue, object parameterValue)
是否是同一天
SqlFunc.DateIsSame(DateTime date1, DateTime date2)
随机数函数,通过排序随机取第一天等操作可以用到
SqlFunc.GetRandom
是否是同一时间 (dataType 可以是年、月、天、小时、分钟、秒和毫秒)
SqlFunc.DateIsSame(DateTime date1, DateTime date2, DateType dataType)
在当前时间加一定时间(dataType 可以是年、月、天、小时、分钟、秒和毫秒)
SqlFunc.DateAdd(DateTime date, int addValue, DateType dataType)
在当前时间加N天
SqlFunc.DateAdd(DateTime date, int addValue)
获取当前时间的年、月、天、小时、分钟、秒或者毫秒
SqlFunc.DateValue(DateTime date, DateType dataType)
范围判段
SqlFunc.Between(object value, object start, object end)
类型转换
SqlFunc.ToInt32(object value)
SqlFunc.ToInt64(object value)
SqlFunc.ToDate(object value)
SqlFunc.ToString(object value)
SqlFunc.ToDecimal(object value)
SqlFunc.ToGuid(object value)
SqlFunc.ToDouble(object value)
SqlFunc.ToBool(object value)
截取字符串
SqlFunc.Substring(object value, int index, int length)
替换字符串
SqlFunc.Replace(object value, string oldChar, string newChar)
获取字符串长度
SqlFunc.Length(object value)
聚合函数
SqlFunc.AggregateSum(TResult thisValue)
SqlFunc.AggregateAvg(TResult thisValue)
SqlFunc.AggregateMin(TResult thisValue)
SqlFunc.AggregateMax(TResult thisValue)
SqlFunc.AggregateCount(TResult thisValue)
将Select中的一列用Sql实现
var s2 = db.Queryable()
.Select(it => new {
id = it.Id,
rowIndex=SqlFunc.MappingColumn(it.Id, " row_number() over(order by id)")
}).ToList();
//SELECT
[ID] AS [id] ,
row_number() over(order by id) AS [rowIndex]
FROM [STudent]
//rowIndex= 变成了 AS [rowIndex]
//SqlFunc.MappingColumn(it.Id, " row_number() over(order by id)") 变成了 row_number() over(order by id)
如果还有不支持的可以写字符串
db.Queryable().Where(“id=@id”,new{id=1}).Select(“id,name”).ToList()
如果还不支持可以下面的自定义扩展SqlFunc让你的代码更漂亮
扩展SqlFunc函数
使用场景
1、当ORM自带的Sqlfunc不能满足你的情况下
2、相当复杂的函数
功能描述
该方法可以让Lambda支持自定义解析, 可以把数据库的自带函数封装起来, 享受一个完美的ORM
当然, 该方法不仅仅只是支持查询里面使用, 对应的查询, 修改, 删除都可以使用自定义Lambda解析, 这里用查询做Demo
public class Demo
{
public static SqlSugarClient GetDb()
{
//Create ext method
var expMethods = new List();
expMethods.Add(new SqlFuncExternal()
{
UniqueMethodName = "MyToString",
MethodValue = (expInfo, dbType, expContext) =>
{
if(dbType==DbType.SqlServer)
return string.Format("CAST({0} AS VARCHAR(MAX))", expInfo.Args[0].MemberName);
else
throw new Exception("未实现");
}
});
var config = new ConnectionConfig()
{
ConnectionString = Config.ConnectionString,
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
ConfigureExternalServices = new ConfigureExternalServices()
{
SqlFuncServices = expMethods//set ext method
}
};
SqlSugarClient db = new SqlSugarClient(config);
return db;
}
public static string MyToString(T str)
{
//这里不能写任何实现代码,需要在上面的配置中实现
throw new NotSupportedException("Can only be used in expressions");
}
public static void Init()
{
var db = GetDb();
var list = db.Queryable().Where(it => MyToString(it.Id) == "1302583").ToList();
var sql = db.Queryable().Where(it => MyToString(it.Id) == "1302583").ToSql();
//生成的Sql CAST([Id] AS VARCHAR(MAX))
Console.WriteLine(sql);
}
}
高级功能
1、数据缓存
http://www.codeisbug.com/Home/Doc?typeId=1214
2、异步
在原有方法后面加Async就是异步方法了
var task1=db.Queryable().FirstAsync();
var task2 = db.Queryable().Where(it=>it.Id==1).ToListAsync();
//分页需要特别注意用法
RefAsync total = 0;
Db.Queryable().ToPageListAsync(1, 2, total);
3、存储复杂结构
数据库将order生成一段JSON字符串进行存储
public class UnitJsonTest
{
[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
[SqlSugar.SugarColumn(ColumnDataType =“varchar(2000)”, IsJson = true)]
public Order Order { get; set; }
public string Name{get;set;}
}
Db.Insertable(new UnitJsonTest() { Name=“json1”,Order = new Order { Id = 1, Name = “order1” } }).ExecuteCommand();
var list = Db.Queryable().ToList();
以上来自官方文档 接下来我们就可以写封装类了