C# 数据操作系列 - 16 SqlSugar 完结篇

前一篇我们详细的介绍了SqlSugar的增删改查,那些已经满足我们在日常工程开发中的使用了。但是还有一点点在开发中并不常用,但是却非常有用的方法。接下来让我们一起来看看还有哪些有意思的内容。

1. 不同寻常的查询

之前介绍了针对单个表的查询,同样也是相对简单的查询模式。虽然开发完全够用,但是难免会遇到一些特殊的情况。而下面这些方法就是为了解决这些意料之外。

1.1 多表查询

SqlSugar提供了一种特殊的多表查询方案,使用IQueryable接口 。来看看是怎样操作的吧:

ISugarQueryable<T, T2> Queryable<T, T2>(Expression<Func<T, T2, object[]>> joinExpression); ISugarQueryable<T, T2> Queryable<T, T2>(ISugarQueryable<T> joinQueryable1, ISugarQueryable<T2> joinQueryable2, Expression<Func<T, T2, bool>> joinExpression) where T : class, new() where T2 : class, new(); ISugarQueryable<T, T2> Queryable<T, T2>(ISugarQueryable<T> joinQueryable1, ISugarQueryable<T2> joinQueryable2, JoinType joinType, Expression<Func<T, T2, bool>> joinExpression) where T : class, new() where T2 : class, new(); ISugarQueryable<T, T2> Queryable<T, T2>(Expression<Func<T, T2, bool>> joinExpression) where T : class, new();

这些方法是属于SqlSugarClient类的方法,SqlSugar提供了最多12个泛型的方法支持,当然实际上开发中能遇到5个表的联查都很少。除非说是在做报表程序,否则就得审查一下数据表模型是否合理了。就以这四个方法为例,介绍一下多表查询如何使用:

先来两个模型类:

public class Person { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } public class Employee { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int Id { get; set; } public string Name { get; set; } public int PersonId { get; set; } [SugarColumn(IsIgnore = true)] public Person Person { get; set; } }

简单的描述一下两个类的关系:一个雇员身份对应一个人,但一个人不一定会有一个雇员身份。

OK,先从第一个方法说起:

var query = context.Client.Queryable<Person, Employee>((pr, em)=>new object[] { JoinType.Left, em.PersonId == pr.Id });

第一个返回,是两个表的连接方式,例如:Left代表左连接,Inner表示内连接,Right表示右连接;第二个返回是两个表之间的连接依据。这是一个固定的形式,返回一个Object数组,其中第一个是连接方式,第二个是通过哪个(些)字段进行连接。

生成的SQL类似如下:

SELECT `pr`.`Id`,`pr`.`Name`,`pr`.`Age` FROM `Person` pr Left JOIN `Employee` em ON ( `em`.`PersonId` = `pr`.`Id` )

第二个方法:

var query = context.Client.Queryable(context.Client.Queryable<Person>(), context.Client.Queryable<Employee>(), (pr, em) => pr.Id == em.PersonId);

这个方法使用内连接连接两个表,最后一个参数用来指定两个表之间的连接字段。

生成的SQL类似如下:

SELECT `pr`.`Id` AS `Person.Id` , `pr`.`Name` AS `Person.Name` , `pr`.`Age` AS `Person.Age` , `em`.`Id` AS `Employee.Id` , `em`.`Name` AS `Employee.Name` , `em`.`PersonId` AS `Employee.PersonId` , `em`.`DeptId` AS `Employee.DeptId` FROM (SELECT `Id`,`Name`,`Age` FROM `Person` ) pr Inner JOIN (SELECT `Id`,`Name`,`PersonId`,`DeptId` FROM `Employee` ) em ON ( `pr`.`Id` = `em`.`PersonId` )

第三个方法在第二个方法的基础上,可以指定连接方式:

var query = context.Client.Queryable(context.Client.Queryable<Person>(), context.Client.Queryable<Employee>(), JoinType.Left, (pr, em) => pr.Id == em.PersonId);

最后一个:

var query = context.Client.Queryable<Person, Employee>((pr, em) => pr.Id == em.PersonId);

直接指定两个表之间的联系方式。

需要指出的是,所有的方法都只是返回了一个可查询对象,如果不进行后续的投影(进行select)则可能会提示主键冲突。而且,所有的方法在进行ToXXX之前都不会立即执行。

1.2 查询函数

SqlSugar添加了很多我们常用的方法,使其可以映射为sql语句。我们来看一下支持哪些内容:

public class SqlFunc { public static TResult AggregateAvg<TResult>(TResult thisValue);//针对这个列进行取平均数统计 public static int AggregateCount<TResult>(TResult thisValue);// 统计这个列数量 等价于 SQL里的 count(x) public static int AggregateDistinctCount<TResult>(TResult thisValue);/ 返回去重之后的数量 public static TResult AggregateMax<TResult>(TResult thisValue);//返回最大值 public static TResult AggregateMin<TResult>(TResult thisValue);// 返回最小值 public static TResult AggregateSum<TResult>(TResult thisValue);// 返回总和 public static bool Between(object value, object start, object end);// 判断列的值是否在两个值之间 public static int CharIndex(string findChar, string searchValue);// SQL 的charindex public static bool Contains(string thisValue, string parameterValue);// 是否包含 public static bool ContainsArray<T>(T[] thisValue, object InField);// 数组是否包含 public static bool ContainsArray<T>(List<T> thisValue, object InField);//列表苏菲包含 public static bool ContainsArrayUseSqlParameters<T>(List<T> thisValue, object InField);// public static bool ContainsArrayUseSqlParameters<T>(T[] thisValue, object InField);// public static DateTime DateAdd(DateTime date, int addValue, DateType dataType);// 时间添加 public static DateTime DateAdd(DateTime date, int addValue);// 日期添加 public static bool DateIsSame(DateTime date1, DateTime date2);// 时间是否相同 public static bool DateIsSame(DateTime? date1, DateTime? date2);//时间是否相同 public static bool DateIsSame(DateTime date1, DateTime date2, DateType dataType);//时间是否相同,根据DateType判断 public static int DateValue(DateTime date, DateType dataType);// 根据dateType, 返回具体的时间值 public static bool EndsWith(string thisValue, string parameterValue);//字符串是否以某些值结尾 public static bool Equals(object thisValue, object parameterValue);//是否相等 public static DateTime GetDate();//返回当前数据库时间 public static string GetRandom();// public static TResult GetSelfAndAutoFill<TResult>(TResult value);// public static bool HasNumber(object thisValue);//返回是否大于0,且不能为Null public static bool HasValue(object thisValue);// 是否有值,且不为Null public static CaseThen IF(bool condition);// sql 里的if判断 public static TResult IIF<TResult>(bool Expression, TResult thenValue, TResult elseValue);// case when public static TResult IsNull<TResult>(TResult thisValue, TResult ifNullValue);// sql 里的 IsNull public static bool IsNullOrEmpty(object thisValue);//判断是否是Null或者空 public static int Length(object value);//取长度 public static TResult MappingColumn<TResult>(TResult oldColumnName, string newColumnName);// 列名映射 public static string MergeString(string value1, string value2); public static string MergeString(string value1, string value2, string value3, string value4); public static string MergeString(string value1, string value2, string value3, string value4, string value5); public static string MergeString(string value1, string value2, string value3, string value4, string value5, string value6); public static string MergeString(string value1, string value2, string value3); public static string MergeString(string value1, string value2, string value3, string value4, string value5, string value6, string value7); public static string Replace(object value, string oldChar, string newChar);// 替换 public static bool StartsWith(string thisValue, string parameterValue); public static Subqueryable<T> Subqueryable<T>() where T : class, new(); public static string Substring(object value, int index, int length);// 获取子串 public static bool ToBool(object value);//类型转换 public static DateTime ToDate(object value);// 类型转换 public static decimal ToDecimal(object value);// 类型转换 public static double ToDouble(object value);// 类型转换 public static Guid ToGuid(object value);// 类型转换 public static int ToInt32(object value);// 类型转换 public static long ToInt64(object value);// 类型转换 public static string ToLower(object thisValue);// 类型转换 public static string ToString(object value);// 类型转换 public static TimeSpan ToTime(object value);// 类型转换 public static string ToUpper(object thisValue);// 类型转换 public static string Trim(object thisValue);// 去除首尾的空格 }

这里的方法大多简单直接,我就不一一演示了。

1.3 动态查询

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzfxgz.html