2026/6/1 12:43:36
网站建设
项目流程
网站设计的主要风格,视频网站发展好应该怎么做,济南建设档案大厦,wordpress获取作者1. 不同寻常的查询
之前介绍了针对单个表的查询#xff0c;同样也是相对简单的查询模式。虽然开发完全够用#xff0c;但是难免会遇到一些特殊的情况。而下面这些方法就是为了解决这些意料之外。
1.1 多表查询
SqlSugar提供了一种特殊的多表查询方案#xff0c;使用IQueryab…1. 不同寻常的查询之前介绍了针对单个表的查询同样也是相对简单的查询模式。虽然开发完全够用但是难免会遇到一些特殊的情况。而下面这些方法就是为了解决这些意料之外。1.1 多表查询SqlSugar提供了一种特殊的多表查询方案使用IQueryable接口 。来看看是怎样操作的吧代码语言javascript复制ISugarQueryableT, T2 QueryableT, T2(ExpressionFuncT, T2, object[] joinExpression); ISugarQueryableT, T2 QueryableT, T2(ISugarQueryableT joinQueryable1, ISugarQueryableT2 joinQueryable2, ExpressionFuncT, T2, bool joinExpression) where T : class, new() where T2 : class, new(); ISugarQueryableT, T2 QueryableT, T2(ISugarQueryableT joinQueryable1, ISugarQueryableT2 joinQueryable2, JoinType joinType, ExpressionFuncT, T2, bool joinExpression) where T : class, new() where T2 : class, new(); ISugarQueryableT, T2 QueryableT, T2(ExpressionFuncT, T2, bool joinExpression) where T : class, new();这些方法是属于SqlSugarClient类的方法SqlSugar提供了最多12个泛型的方法支持当然实际上开发中能遇到5个表的联查都很少。除非说是在做报表程序否则就得审查一下数据表模型是否合理了。就以这四个方法为例介绍一下多表查询如何使用先来两个模型类代码语言javascript复制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先从第一个方法说起代码语言javascript复制var query context.Client.QueryablePerson, Employee((pr, em)new object[] { JoinType.Left, em.PersonId pr.Id });第一个返回是两个表的连接方式例如Left代表左连接Inner表示内连接Right表示右连接第二个返回是两个表之间的连接依据。这是一个固定的形式返回一个Object数组其中第一个是连接方式第二个是通过哪个些字段进行连接。生成的SQL类似如下代码语言javascript复制SELECT pr.Id,pr.Name,pr.Age FROM Person pr Left JOIN Employee em ON ( em.PersonId pr.Id )第二个方法代码语言javascript复制var query context.Client.Queryable(context.Client.QueryablePerson(), context.Client.QueryableEmployee(), (pr, em) pr.Id em.PersonId);这个方法使用内连接连接两个表最后一个参数用来指定两个表之间的连接字段。生成的SQL类似如下代码语言javascript复制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 )第三个方法在第二个方法的基础上可以指定连接方式代码语言javascript复制var query context.Client.Queryable(context.Client.QueryablePerson(), context.Client.QueryableEmployee(), JoinType.Left, (pr, em) pr.Id em.PersonId);最后一个代码语言javascript复制var query context.Client.QueryablePerson, Employee((pr, em) pr.Id em.PersonId);直接指定两个表之间的联系方式。需要指出的是所有的方法都只是返回了一个可查询对象如果不进行后续的投影进行select则可能会提示主键冲突。而且所有的方法在进行ToXXX之前都不会立即执行。1.2 查询函数SqlSugar添加了很多我们常用的方法使其可以映射为sql语句。我们来看一下支持哪些内容代码语言javascript复制public class SqlFunc { public static TResult AggregateAvgTResult(TResult thisValue);//针对这个列进行取平均数统计 public static int AggregateCountTResult(TResult thisValue);// 统计这个列数量 等价于 SQL里的 count(x) public static int AggregateDistinctCountTResult(TResult thisValue);/ 返回去重之后的数量 public static TResult AggregateMaxTResult(TResult thisValue);//返回最大值 public static TResult AggregateMinTResult(TResult thisValue);// 返回最小值 public static TResult AggregateSumTResult(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 ContainsArrayT(T[] thisValue, object InField);// 数组是否包含 public static bool ContainsArrayT(ListT thisValue, object InField);//列表苏菲包含 public static bool ContainsArrayUseSqlParametersT(ListT thisValue, object InField);// public static bool ContainsArrayUseSqlParametersT(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 GetSelfAndAutoFillTResult(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 IIFTResult(bool Expression, TResult thenValue, TResult elseValue);// case when public static TResult IsNullTResult(TResult thisValue, TResult ifNullValue);// sql 里的 IsNull public static bool IsNullOrEmpty(object thisValue);//判断是否是Null或者空 public static int Length(object value);//取长度 public static TResult MappingColumnTResult(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 SubqueryableT SubqueryableT() 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 动态查询之前我们写的查询条件都是固定好的至少在编程的时候就知道最终查询条件是什么了。但是在开发过程中有时候并不会那么早的知道最终查询条件或者说查询需要根据用户输入来调整查询条件那么如何实现呢常见的解决方案有以下几种使用SQL语句动态拼接SQL语句然后根据SQL语句执行返回结果在使用Lambda表达式时进行动态拼接Lambda表达式获取IQueryable接口然后根据条件添加方法进行查询这三种方法各有优略使用查询接口会有一个明显的问题就是对应用层开放了更高的权限使用SQL语句也是同样的道理。所以更符合逻辑的是使用动态拼接Lambda表达式。当然SqlSugar在这三种方案之上提供了另外两种方案正是上一篇文中提到的IConditionalModel和WhereIF。我们先来看一下IConditionalModel如何使用代码语言javascript复制var conditions new ListIConditionalModel(); var query context.Client.QueryablePerson().Where(conditions);可以在Where中传入IConditionModel类型。SqlSugar提供了两个受支持的实现类代码语言javascript复制public class ConditionalCollections : IConditionalModel { public ConditionalCollections(); public ListKeyValuePairWhereType, ConditionalModel ConditionalList { get; set; } } public class ConditionalModel : IConditionalModel { public ConditionalModel(); public string FieldName { get; set; } public string FieldValue { get; set; } public ConditionalType ConditionalType { get; set; } public Funcstring, object FieldValueConvertFunc { get; set; } }对于一个集合里的兄弟 ConditionModel表示查询条件都是 and 关系。而ConditionCollections则不同其中ConditionList表示是一个键值对集合。键是WhereType类型ConditionModel是值。我们先说说 WhereType代码语言javascript复制public enum WhereType { And 0, Or 1 }分别表示AndOr。怎样理解呢就是说这一条键值对与前一个关系模型是And还是Or。看一下示例代码语言javascript复制// and id100 and (id1 or id2 and id1) conModels.Add(new ConditionalModel() { FieldName id, ConditionalType ConditionalType.Equal, FieldValue 100 }); conModels.Add(new ConditionalCollections() { ConditionalList new ListKeyValuePairWhereType, SqlSugar.ConditionalModel() { new KeyValuePairWhereType, ConditionalModel ( WhereType.And , new ConditionalModel() { FieldName id, ConditionalType ConditionalType.Equal, FieldValue 1 }), new KeyValuePairWhereType, ConditionalModel (WhereType.Or, new ConditionalModel() { FieldName id, ConditionalType ConditionalType.Equal, FieldValue 2 }), new KeyValuePairWhereType, ConditionalModel ( WhereType.And, new ConditionalModel() { FieldName id, ConditionalType ConditionalType.Equal, FieldValue 2 }) } }); var student db.QueryableStudent().Where(conModels).ToList();继续看一下WhereIFWhereIF的使用就相对简单一点代码语言javascript复制ISugarQueryableT WhereIF(bool isWhere, ExpressionFuncT, bool expression);示例代码代码语言javascript复制var query context.Client.QueryablePerson().WhereIF(string.IsNullOrEmpty(input), pp.Age10);理解起来也很容易第一个参数如何结果为False则不执行后续的查询否则就执行。2. 一些高级玩法除了增删改查SqlSugar还提供了一些别的有意思的机制继续我们的探索吧。2.1 批量操作SqlSugar提供了一种一次性记录很多操作然后统一提交执行的模式之前的操作都是仅支持批量插入、批量修改、批量删除。在这种模式下SqlSugar还支持了批量插入、修改、删除。也就是说在一个批处理中即可以插入也可以修改还可以删除。那么我们来看如何让这个功能为我们所用吧代码语言javascript复制void AddQueue();在IDeleteable、IInsertable、IUpdateable、ISugarQueryable都有这个方法一旦调用这个方法就表示该条指令进行缓存不立即执行直到调用SqlSugarClient.SaveQueues()。通过调用SaveQueues()保存到数据库中。值得注意的是SqlSugar 虽然支持将查询也加入到批量操作的支持中但是这部分在我看来更像是为了保证接口一致化而作的。个人并不推荐在批处理中加入查询因为查询更多的需要及时准确快速如果一旦陷入批处理中查询就无法准确快速的返回数据了。 这样对于设定批处理的初衷反而是违背的。当然最重要的一点实际开发中这种情况很少遇到。2.2 事务SQL本身支持事务大多数ORM都支持事务SqlSugar也不例外。SqlSugar通过哪些方法来自己实现一个事务呢在SqlSugarClient中执行代码语言javascript复制public void BeginTran();会将SqlSugarClient做一个事务标记表示之后的操作都是在事务中直到事务提交或者回滚。在SimpleClient中执行代码语言javascript复制public ITenant AsTenant();返回一个ITenant实例然后通过这个实例提交事务或者回滚事务。注意SqlSugar所有的事务都是针对 SqlSugarClient级别的也就是说一个事务一个SqlSugarClient。2.3 原生SQL执行SqlSugar在很多地方都添加了原生Sql的支持。比如说通过如下这种方式可以使用Sql语句进行查询代码语言javascript复制var t12 context.Client.SqlQueryableStudent(select * from student).Where(itit.id0).ToPageList(1, 2);通过以下这种方式执行SQL代码语言javascript复制context.Client.Ado.ExecuteCommand(sql, parameters)然后通过以下方式执行存储过程代码语言javascript复制context.Client.Ado.UseStoredProcedure()