FreeSql (十五)查询数据


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

static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
    .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
    .Build(); //请务必定义成 Singleton 单例模式

class Topic
{
    [Column(IsIdentity = true)]
    public int Id { get; set; }
    public string Title { get; set; }
    public int Clicks { get; set; }
    public DateTime CreateTime { get; set; }

    public int CategoryId { get; set; }
}

查询数据

fsql.Select()
  .Where(a => a.Id == 10)
  .ToList();
//SELECT a.`Id`, a.`Clicks`, a.`CategoryId`, a.`Title`, a.`CreateTime` 
//FROM `Topic` a 
//WHERE (a.`Id` = 10)

fsql.Select()
  .Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100)
  .ToList();
//SELECT a.`Id`, a.`Clicks`, a.`CategoryId`, a.`Title`, a.`CreateTime` 
//FROM `Topic` a 
//WHERE (a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100)

fsql.Select()
  .Where(a => new []{1,2,3}.Contains(a.Id))
  .ToList();
//SELECT a.`Id`, a.`Clicks`, a.`CategoryId`, a.`Title`, a.`CreateTime` 
//FROM `Topic` a 
//WHERE (a.`Id` in (1,2,3))

WithSql

fsql.Select()
  .WithSql("select * from Topic where clicks > 10")
  .Page(1, 10)
  .ToList()
//SELECT a.`Id`, a.`Clicks`, a.`CategoryId`, a.`Title`, a.`CreateTime` 
//FROM (select * from Topic where clicks > 10) a 

WithSql 使用多次为 UNION ALL 查询

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(@"
{
  ""Logic"" : ""Or"",
  ""Filters"" :
  [
    {
      ""Field"" : ""Code"", ""Operator"" : ""NotContains"", ""Value"" : ""val1"", 
      ""Filters"" : [ { ""Field"" : ""Name"", ""Operator"" : ""NotStartsWith"", ""Value"" : ""val2"" } ]
    },
    {
      ""Field"" : ""Parent.Code"", ""Operator"" : ""Eq"", ""Value"" : ""val11"",
      ""Filters"" : [ { ""Field"" : ""Parent.Name"", ""Operator"" : ""Contains"", ""Value"" : ""val22"" } ]
    }
  ]
}
");
fsql.Select().WhereDynamicFilter(dyfilter).ToList();
//SELECT a.""Code"", a.""Name"", a.""ParentCode"", a__Parent.""Code"" as4, a__Parent.""Name"" as5, a__Parent.""ParentCode"" as6 
//FROM ""D_District"" a 
//LEFT JOIN ""D_District"" a__Parent ON a__Parent.""Code"" = a.""ParentCode"" 
//WHERE (not((a.""Code"") LIKE '%val1%') AND not((a.""Name"") LIKE 'val2%') OR a__Parent.""Code"" = 'val11' AND (a__Parent.""Name"") LIKE '%val22%')

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

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 })
Disdinct .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个表
【其他】
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) 递归查询父子关系表

系列文章导航

  • (十五)查询数据