0. 前言
前一篇我們詳細的介紹了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,