查询
2881099 edited this page 2023-12-14 19:40:29 +08:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

中文 | English

FreeSql在查询数据下足了功夫链式查询语法、多表查询、表达式函数支持得非常到位。

《分页查询》 《仓储层Repository》 《读写分离》
《单表查询》 《过滤器、全局过滤器》 《LinqToSql》
《多表查询》 《延时加载》 《性能》
《嵌套查询》 《贪婪加载》 《分表分库》
《分组聚合查询》 《表达式函数》 《多租户》
《返回数据》

SqlServer WithLock/WithIndex

var list = fsql.Select<Region>()
    .WithLock()
    .Limit(1).ToList();
//SELECT TOP 1 ... FROM [Region] a With(NoLock)

var list = fsql.Select<Region>()
    .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
    .Limit(1).ToList();
//SELECT TOP 1 ... FROM [Region] a With(NoLock, NoWait)

var list = fsql.Select<Region>()
    .WithLock()
    .WithIndex("idx_01")
    .Limit(1).ToList();
//SELECT TOP 1 ... FROM [Region] a With(index=idx_01, NoLock)

多表:

var list = Select<Region, T2>()
    .InnerJoin((a, b) => a.x == b.xx)
    .WithLock(SqlServerLock.NoLock, new Dictionary<Type, bool>
    {
        [typeof(T2)] = false
    })
    .WithIndex("idx_01", new Dictionary<Type, string>
    {
        [typeof(T2)] = "idx_02"
    })
    .Limit(1).ToList();
//SELECT TOP 1 ..
//FROM [Region] a With(index=idx_01, NoLock) 
//INNER JOIN [T2] b With(index=idx_02) ON a.[x] = b.[xx]

全局设置 NoLock

//所有实体类生效
fsql.SetGlobalSelectWithLock(SqlServerLock.NoLock, null);

//【指定】实体类生效
fsql.SetGlobalSelectWithLock(SqlServerLock.NoLock, new Dictionary<Type, bool>
{
    [typeof(Region)] = true,
    [typeof(T2)] = true
});

特别介绍 WhereDynamicFilter

《高效理解 FreeSql WhereDynamicFilter深入了解设计初衷》

ISelect.WhereDynamicFilter 方法实现动态过滤条件(与前端交互),支持的操作符:

  • Contains/StartsWith/EndsWith/NotContains/NotStartsWith/NotEndsWith包含/不包含like '%xx%',或者 like 'xx%',或者 like '%xx'
  • Equal/NotEqual等于/不等于
  • GreaterThan/GreaterThanOrEqual大于/大于等于
  • LessThan/LessThanOrEqual小于/小于等于
  • Range范围查询
  • DateRange日期范围有特殊处理 value[1] + 1
  • Any/NotAny是否符合 value 中任何一项(直白的说是 SQL IN
  • Custom自定义解析
DynamicFilterInfo dyfilter = JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
{
  ""Logic"": ""And"",
  ""Filters"":
  [
    { ""Field"": ""id"", ""Operator"": ""Equals"", ""Value"": 1 },
    {
      ""Logic"": ""Or"",
      ""Filters"":
      [
        { ""Field"": ""id"", ""Operator"": ""Equals"", ""Value"": 2 },
        { ""Field"": ""id"", ""Operator"": ""Equals"", ""Value"": 3 }
      ]
    }
  ]
}");
fsql.Select<Region>().WhereDynamicFilter(dyfilter).ToList();
//WHERE id = 1 AND (id = 2 OR id = 3)

动态表名ISelect.AsTable((t, old) => $"{old}_201903")

动态排序ISelect.OrderByPropertyName("Parent.Code")

动态返回ISelect.ToDataTableByPropertyName(new string[] { "Parent.Code", "Id" })

动态贪婪加载ISelect.IncludeByPropertyName("Parent.Parent").IncludeByPropertyName("Parent.Childs")

API

方法 返回值 参数 描述
ToSql string 返回即将执行的SQL语句
ToList List<T1> 执行SQL查询返回 T1 实体所有字段的记录,若存在导航属性则一起查询返回,记录不存在时返回 Count 为 0 的列表
ToList<T> List<T> Lambda 执行SQL查询返回指定字段的记录记录不存在时返回 Count 为 0 的列表
ToList<T> List<T> string field 执行SQL查询返回 field 指定字段的记录,并以元组或基础类型(int,string,long)接收,记录不存在时返回 Count 为 0 的列表
ToOne T1 执行SQL查询返回 T1 实体所有字段的第一条记录,记录不存在时返回 null
ToAggregate<T> List<T> Lambda 执行SQL查询返回指定字段的聚合结果适合不需要 GroupBy 的场景)
Any bool 执行SQL查询是否有记录
Sum T Lambda 指定一个列求和
Min T Lambda 指定一个列求最小值
Max T Lambda 指定一个列求最大值
Avg T Lambda 指定一个列求平均值
【分页】
Count long 查询的记录数量
Count <this> out long 查询的记录数量以参数out形式返回
Skip <this> int offset 查询向后偏移行数
Offset <this> int offset 查询向后偏移行数
Limit <this> int limit 查询多少条数据
Take <this> int limit 查询多少条数据
Page <this> int pageIndex, int pageSize 分页
【条件】
Where <this> Lambda 支持多表查询表达式多次使用相当于AND
WhereIf <this> bool, Lambda 支持多表查询表达式
Where <this> string, parms 原生sql语法条件Where("id = @id", new { id = 1 })注意前缀@根据具体数据库决定
WhereIf <this> bool, string, parms 原生sql语法条件WhereIf(true, "id = @id", new { id = 1 }) ,注意前缀@根据具体数据库决定
WhereCascade <this> Lambda 实现多表查询时,向每个表中附加条件
WhereDynamicFilter <this> DynamicFilterInfo 动态过滤条件(与前端交互)
【分组】
GroupBy <this> Lambda 按选择的列分组GroupBy(a => a.Name)
GroupBy <this> string, parms 按原生sql语法分组GroupBy("concat(name, @cc)", new { cc = 1 }) ,注意前缀@根据具体数据库决定
Having <this> string, parms 按原生sql语法聚合条件过滤Having("count(name) = @cc", new { cc = 1 }),注意前缀@根据具体数据库决定
Distinct <this> .Distinct().ToList(x => x.GroupName) 是对指定字段
【排序】
OrderBy <this> Lambda 按列排序OrderBy(a => a.Time),可多次使用
OrderByDescending <this> Lambda 按列倒向排序OrderByDescending(a => a.Time)
OrderBy <this> string, parms 按原生sql语法排序OrderBy("count(name) + @cc", new { cc = 1 })
OrderByPropertyName string, bool 按属性名字符串排序(支持导航属性)
【联表】
LeftJoin <this> Lambda 左联查询,可使用导航属性,或指定关联的实体类型
InnerJoin <this> Lambda 联接查询,可使用导航属性,或指定关联的实体类型
RightJoin <this> Lambda 右联查询,可使用导航属性,或指定关联的实体类型
LeftJoin <this> string, parms 左联查询使用原生sql语法LeftJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 })
InnerJoin <this> string, parms 联接查询使用原生sql语法InnerJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 })
RightJoin <this> string, parms 右联查询使用原生sql语法RightJoin("type b on b.id = a.id and b.clicks > @clicks", new { clicks = 1 })
From <this> Lambda 多表查询3个表以上使用非常方便目前设计最大支持10个表
FromQuery ISelect<T1, T2> ISelect<T2> 单表连成双表查询
WithTempQuery ISelect<T1> Lambda 将单表或多表查询嵌套成单表查询
WithMemory ISelect<T1> List<T1> 使用内存数据查询
UnionAll ISelect<T1> ISelect<T1>[] 联合查询
【其他】
As <this> string alias = "a" 指定别名
Master <this> 指定从主库查询(默认查询从库)
CommandTimeout <this> int 命令超时设置(秒)
WithTransaction <this> DbTransaction 设置事务对象
WithConnection <this> DbConnection 设置连接对象
WithLock <this> Enum SqlServer NoLock 等特有的设置
ForUpdate <this> bool 排他更新锁,对不同的数据库已作适配,详细说明见注释
AsQueryable IQueryable 将 ISelect 转换为 IQueryable此方法主要用于扩展比如abp IRepository GetAll() 接口方法需要返回 IQueryable 对象。注意IQueryable 方法污染较为严重,请尽量避免此转换
InsertInto int string, Lambda 将查询转换为 INSERT INTO tableName SELECT ... FROM t 执行插入
ToUpdate IUpdate<TEntity> 将查询转为更新对象
ToDelete IDelete<TEntity> 将查询转为删除对象
ToTreeList List<TEntity> 将父子关系的数据以 TreeList 的形式返回
AsTreeCte ISelect (up, pathSelector, level) 递归查询父子关系表