Skip to content
2881099 edited this page Dec 14, 2023 · 57 revisions

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

Clone this wiki locally