From f1b5973e3297db7adc7970ba38fc17211d480526 Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Thu, 3 Aug 2017 23:12:44 +0800 Subject: [PATCH] Add Oracle Test --- Src/Asp.Net/OracleTest/Config.cs | 13 + Src/Asp.Net/OracleTest/Demos/1_Query.cs | 373 +++++++++ Src/Asp.Net/OracleTest/Demos/2_Update.cs | 63 ++ Src/Asp.Net/OracleTest/Demos/3_Insert.cs | 58 ++ Src/Asp.Net/OracleTest/Demos/4_Delete.cs | 33 + Src/Asp.Net/OracleTest/Demos/5_CodeFirst.cs | 53 ++ Src/Asp.Net/OracleTest/Demos/5_DbFirst.cs | 72 ++ .../OracleTest/Demos/6_ComplexModel.cs | 78 ++ Src/Asp.Net/OracleTest/Demos/7_Filter.cs | 72 ++ Src/Asp.Net/OracleTest/Demos/8_JoinSql.cs | 51 ++ Src/Asp.Net/OracleTest/Demos/DemoBase.cs | 23 + Src/Asp.Net/OracleTest/Models/DataTestInfo.cs | 135 ++++ .../OracleTest/Models/DataTestInfo2.cs | 44 ++ Src/Asp.Net/OracleTest/Models/Enum.cs | 22 + Src/Asp.Net/OracleTest/Models/School.cs | 17 + Src/Asp.Net/OracleTest/Models/Student.cs | 22 + .../OracleTest/Models/ViewModelStudent.cs | 22 + Src/Asp.Net/OracleTest/OracleTest.csproj | 104 +++ .../OracleTest/OtherDll/SyntacticSugar.dll | Bin 0 -> 119808 bytes .../PerformanceTesting/PerformanceBase.cs | 30 + .../PerformanceTesting/SqlSugarPerformance.cs | 34 + Src/Asp.Net/OracleTest/Program.cs | 50 ++ .../OracleTest/Properties/AssemblyInfo.cs | 36 + Src/Asp.Net/OracleTest/UnitTest/DataTest.cs | 72 ++ Src/Asp.Net/OracleTest/UnitTest/DataTest2.cs | 39 + Src/Asp.Net/OracleTest/UnitTest/Delete.cs | 61 ++ Src/Asp.Net/OracleTest/UnitTest/EnumTest.cs | 39 + .../UnitTest/ExpressionTest/Field.cs | 51 ++ .../UnitTest/ExpressionTest/Method.cs | 709 ++++++++++++++++++ .../UnitTest/ExpressionTest/Select.cs | 186 +++++ .../UnitTest/ExpressionTest/Where.cs | 387 ++++++++++ Src/Asp.Net/OracleTest/UnitTest/Insert.cs | 152 ++++ Src/Asp.Net/OracleTest/UnitTest/Mapping .cs | 69 ++ .../OracleTest/UnitTest/Query/JoinQuery.cs | 140 ++++ .../OracleTest/UnitTest/Query/SelectQuery.cs | 88 +++ .../OracleTest/UnitTest/Query/SingleQuery.cs | 118 +++ .../OracleTest/UnitTest/Setting/Attribute.cs | 20 + .../OracleTest/UnitTest/Setting/AutoClose.cs | 27 + .../OracleTest/UnitTest/Setting/MapColumn.cs | 14 + .../OracleTest/UnitTest/Setting/MapTable.cs | 23 + .../OracleTest/UnitTest/UnitTestBase.cs | 55 ++ Src/Asp.Net/OracleTest/UnitTest/Update.cs | 165 ++++ Src/Asp.Net/SqlSugar.sln | 6 + 43 files changed, 3826 insertions(+) create mode 100644 Src/Asp.Net/OracleTest/Config.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/1_Query.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/2_Update.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/3_Insert.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/4_Delete.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/5_CodeFirst.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/5_DbFirst.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/6_ComplexModel.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/7_Filter.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/8_JoinSql.cs create mode 100644 Src/Asp.Net/OracleTest/Demos/DemoBase.cs create mode 100644 Src/Asp.Net/OracleTest/Models/DataTestInfo.cs create mode 100644 Src/Asp.Net/OracleTest/Models/DataTestInfo2.cs create mode 100644 Src/Asp.Net/OracleTest/Models/Enum.cs create mode 100644 Src/Asp.Net/OracleTest/Models/School.cs create mode 100644 Src/Asp.Net/OracleTest/Models/Student.cs create mode 100644 Src/Asp.Net/OracleTest/Models/ViewModelStudent.cs create mode 100644 Src/Asp.Net/OracleTest/OracleTest.csproj create mode 100644 Src/Asp.Net/OracleTest/OtherDll/SyntacticSugar.dll create mode 100644 Src/Asp.Net/OracleTest/PerformanceTesting/PerformanceBase.cs create mode 100644 Src/Asp.Net/OracleTest/PerformanceTesting/SqlSugarPerformance.cs create mode 100644 Src/Asp.Net/OracleTest/Program.cs create mode 100644 Src/Asp.Net/OracleTest/Properties/AssemblyInfo.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/DataTest.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/DataTest2.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Delete.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/EnumTest.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Field.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Method.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Select.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Where.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Insert.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Mapping .cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Query/JoinQuery.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Query/SelectQuery.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Query/SingleQuery.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Setting/Attribute.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Setting/AutoClose.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Setting/MapColumn.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Setting/MapTable.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/UnitTestBase.cs create mode 100644 Src/Asp.Net/OracleTest/UnitTest/Update.cs diff --git a/Src/Asp.Net/OracleTest/Config.cs b/Src/Asp.Net/OracleTest/Config.cs new file mode 100644 index 000000000..540bf35ba --- /dev/null +++ b/Src/Asp.Net/OracleTest/Config.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest +{ + public class Config + { + public static string ConnectionString = "server=.;uid=sa;pwd=sasa;database=SqlSugar4XTest"; + } +} diff --git a/Src/Asp.Net/OracleTest/Demos/1_Query.cs b/Src/Asp.Net/OracleTest/Demos/1_Query.cs new file mode 100644 index 000000000..cdc2003c0 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/1_Query.cs @@ -0,0 +1,373 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.Demo +{ + public class Query : DemoBase + { + + public static void Init() + { + Easy(); + Page(); + Where(); + Join(); + Funs(); + Select(); + Ado(); + Group(); + Sqlable(); + Tran(); + StoredProcedure(); + Enum(); + Simple(); + } + + private static void Simple() + { + //SqlSugarClient + var db = GetInstance(); + var student1 = db.Queryable().InSingle(1); + + //get SimpleClient + var sdb = db.SimpleClient; + var student2 = sdb.GetById(1); + sdb.DeleteById(1); + sdb.Insert(new Student() { Name = "xx" }); + sdb.Update(it => new Student { Name = "newvalue" }, it => it.Id == 1);//only update name where id=1 + sdb.Update(new Student() { Name="newavalue" ,Id=1});//update all where id=1 + + //SimpleClient Get SqlSugarClient + var student3=sdb.FullClient.Queryable().InSingle(1); + + } + + private static void StoredProcedure() + { + var db = GetInstance(); + //1. no result + db.Ado.UseStoredProcedure(() => + { + string spName = "sp_help"; + var getSpReslut = db.Ado.SqlQueryDynamic(spName, new { objname = "student" }); + }); + + //2. has result + var result = db.Ado.UseStoredProcedure(() => + { + string spName = "sp_help"; + return db.Ado.SqlQueryDynamic(spName, new { objname = "student" }); + }); + + //2. has output + object outPutValue; + var outputResult = db.Ado.UseStoredProcedure(() => + { + string spName = "sp_school"; + var p1 = new SugarParameter("@p1", "1"); + var p2 = new SugarParameter("@p2", null, true);//isOutput=true + var dbResult = db.Ado.SqlQueryDynamic(spName, new SugarParameter[] { p1, p2 }); + outPutValue = p2.Value; + return dbResult; + }); + } + private static void Tran() + { + var db = GetInstance(); + var x=db.Insertable(new Student() { CreateTime = DateTime.Now, Name = "tran" }).ExecuteCommand(); + //1. no result + var result = db.Ado.UseTran(() => + { + + var beginCount = db.Queryable().ToList(); + db.Ado.ExecuteCommand("delete student"); + var endCount = db.Queryable().Count(); + throw new Exception("error haha"); + }); + var count = db.Queryable().Count(); + + //2 has result + var result2 = db.Ado.UseTran>(() => + { + return db.Queryable().ToList(); + }); + + //3 use try + try + { + db.Ado.BeginTran(); + + db.Ado.CommitTran(); + } + catch (Exception) + { + db.Ado.RollbackTran(); + throw; + } + } + private static void Group() + { + var db = GetInstance(); + var list = db.Queryable() + .GroupBy(it => it.Name) + .GroupBy(it => it.Id).Having(it => SqlFunc.AggregateAvg(it.Id) > 0) + .Select(it => new { idAvg = SqlFunc.AggregateAvg(it.Id), name = it.Name }).ToList(); + + + var list2 = db.Queryable() + .GroupBy(it => new { it.Id, it.Name }).Having(it => SqlFunc.AggregateAvg(it.Id) > 0) + .Select(it => new { idAvg = SqlFunc.AggregateAvg(it.Id), name = it.Name }).ToList(); + //SQL: + //SELECT AVG([Id]) AS[idAvg], [Name] AS[name] FROM[Student] GROUP BY[Name],[Id] HAVING(AVG([Id]) > 0 ) + + // group id,name take first + var list3 = db.Queryable() + .PartitionBy(it => new { it.Id, it.Name }).Take(1).ToList(); + + int count = 0; + + var list4 = db.Queryable((st, sc) => st.SchoolId == sc.Id) + .PartitionBy(st => new { st.Name }).Take(1).OrderBy(st => st.Id,OrderByType.Desc).Select(st => st).ToPageList(1, 1000, ref count); + + //SqlFunc.AggregateSum(object thisValue) + //SqlFunc.AggregateAvg(TResult thisValue) + //SqlFunc.AggregateMin(object thisValue) + //SqlFunc.AggregateMax(object thisValue) + //SqlFunc.AggregateCount(object thisValue) + } + private static void Ado() + { + var db = GetInstance(); + db.Ado.BeginTran(); + var t1 = db.Ado.SqlQuery("select 'a'"); + var t2 = db.Ado.GetInt("select 1"); + var t3 = db.Ado.GetDataTable("select 1 as id"); + db.Ado.CommitTran(); + //more + //db.Ado.GetXXX... + } + public static void Easy() + { + var db = GetInstance(); + var getAll = db.Queryable().ToList(); + var getAllOrder = db.Queryable().OrderBy(it => it.Id).OrderBy(it => it.Name, OrderByType.Desc).ToList(); + var getId = db.Queryable().Select(it => it.Id).ToList(); + var getNew = db.Queryable().Where(it => it.Id == 1).Select(it => new { id = SqlFunc.IIF(it.Id == 0, 1, it.Id), it.Name, it.SchoolId }).ToList(); + var getAllNoLock = db.Queryable().With(SqlWith.NoLock).ToList(); + var getByPrimaryKey = db.Queryable().InSingle(2); + var getSingleOrDefault = db.Queryable().Single(); + var getFirstOrDefault = db.Queryable().First(); + var getByWhere = db.Queryable().Where(it => it.Id == 1 || it.Name == "a").ToList(); + var getByFuns = db.Queryable().Where(it => SqlFunc.IsNullOrEmpty(it.Name)).ToList(); + var sum = db.Queryable().Select(it => it.SchoolId).ToList(); + var sum2 = db.Queryable((st,sc)=>st.SchoolId==sc.Id).Sum((st,sc) => sc.Id); + var isAny = db.Queryable().Where(it => it.Id == -1).Any(); + var isAny2 = db.Queryable().Any(it => it.Id == -1); + var getListByRename = db.Queryable().AS("Student").ToList(); + var in1 = db.Queryable().In(it => it.Id, new int[] { 1, 2, 3 }).ToList(); + var in2 = db.Queryable().In(new int[] { 1, 2, 3 }).ToList(); + int[] array = new int[] { 1, 2 }; + var in3 = db.Queryable().Where(it => SqlFunc.ContainsArray(array, it.Id)).ToList(); + var group = db.Queryable().GroupBy(it => it.Id) + .Having(it => SqlFunc.AggregateCount(it.Id) > 10) + .Select(it => new { id = SqlFunc.AggregateCount(it.Id) }).ToList(); + + var between = db.Queryable().Where(it => SqlFunc.Between(it.Id, 1, 20)).ToList(); + + var getTodayList = db.Queryable().Where(it => SqlFunc.DateIsSame(it.CreateTime, DateTime.Now)).ToList(); + + var joinSql = db.Queryable("student", "s").OrderBy("id").Select("id,name").ToPageList(1, 2); + } + public static void Page() + { + var db = GetInstance(); + var pageIndex = 1; + var pageSize = 2; + var totalCount = 0; + //page + var page = db.Queryable().OrderBy(it => it.Id).ToPageList(pageIndex, pageSize, ref totalCount); + + //page join + var pageJoin = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).ToPageList(pageIndex, pageSize, ref totalCount); + + //top 5 + var top5 = db.Queryable().Take(5).ToList(); + + //skip5 + var skip5 = db.Queryable().Skip(5).ToList(); + } + public static void Where() + { + var db = GetInstance(); + //join + var list = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }) + .Where((st, sc) => sc.Id == 1) + .Where((st, sc) => st.Id == 1) + .Where((st, sc) => st.Id == 1 && sc.Id == 2).ToList(); + + //SELECT [st].[Id],[st].[SchoolId],[st].[Name],[st].[CreateTime] FROM [Student] st + //Left JOIN School sc ON ( [st].[SchoolId] = [sc].[Id] ) + //WHERE ( [sc].[Id] = @Id0 ) AND ( [st].[Id] = @Id1 ) AND (( [st].[Id] = @Id2 ) AND ( [sc].[Id] = @Id3 )) + + + //Where If + string name = null; + string name2 = "sunkaixuan"; + var list2 = db.Queryable() + .WhereIF(!string.IsNullOrEmpty(name), it => it.Name == name) + .WhereIF(!string.IsNullOrEmpty(name2), it => it.Name == name2).ToList(); + + + + //join + var list3 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }) + .WhereIF(false, (st, sc) => sc.Id == 1) + .WhereIF(false, (st, sc) => st.Id == 1).ToList(); + } + public static void Join() + { + var db = GetInstance(); + //join 2 + var list = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }) + .Where(st => st.Name == "jack").ToList(); + + //join 3 + var list2 = db.Queryable((st, sc, st2) => new object[] { + JoinType.Left,st.SchoolId==sc.Id, + JoinType.Left,st.SchoolId==st2.Id + }) + .Where((st, sc, st2) => st2.Id == 1 || sc.Id == 1 || st.Id == 1).ToList(); + + //join return List + var list3 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).Select((st, sc) => new ViewModelStudent { Name = st.Name, SchoolId = sc.Id }).ToList(); + + //join Order By (order by st.id desc,sc.id desc) + var list4 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }) + .OrderBy(st => st.Id, OrderByType.Desc) + .OrderBy((st, sc) => sc.Id, OrderByType.Desc) + .Select((st, sc) => new ViewModelStudent { Name = st.Name, SchoolId = sc.Id }).ToList(); + + + //join 2 + var list4_1 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id&& st.Name == "jack" + }).ToList(); + + + //The simple use of Join 2 table + var list5 = db.Queryable((st, sc) => st.SchoolId == sc.Id).Select((st,sc)=>new {st.Name,st.Id,schoolName=sc.Name}).ToList(); + + //join 3 table + var list6 = db.Queryable((st, sc,sc2) => st.SchoolId == sc.Id&&sc.Id==sc2.Id) + .Select((st, sc,sc2) => new { st.Name, st.Id, schoolName = sc.Name,schoolName2=sc2.Name }).ToList(); + + //join 3 table page + var list7= db.Queryable((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id) + .Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToPageList(1,2); + + //join 3 table page + var list8 = db.Queryable((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id) + .OrderBy(st=>st.Id) + .Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToPageList(1, 2); + } + public static void Funs() + { + var db = GetInstance(); + var t1 = db.Queryable().Where(it => SqlFunc.ToLower(it.Name) == SqlFunc.ToLower("JACK")).ToList(); + //SELECT [Id],[SchoolId],[Name],[CreateTime] FROM [Student] WHERE ((LOWER([Name])) = (LOWER(@MethodConst0)) ) + + /***More Functions***/ + //SqlFunc.IsNullOrEmpty(object thisValue) + //SqlFunc.ToLower(object thisValue) + //SqlFunc.string ToUpper(object thisValue) + //SqlFunc.string Trim(object thisValue) + //SqlFunc.bool Contains(string thisValue, string parameterValue) + //SqlFunc.ContainsArray(object[] thisValue, string parameterValue) + //SqlFunc.StartsWith(object thisValue, string parameterValue) + //SqlFunc.EndsWith(object thisValue, string parameterValue) + //SqlFunc.Equals(object thisValue, object parameterValue) + //SqlFunc.DateIsSame(DateTime date1, DateTime date2) + //SqlFunc.DateIsSame(DateTime date1, DateTime date2, DateType dataType) + //SqlFunc.DateAdd(DateTime date, int addValue, DateType millisecond) + //SqlFunc.DateAdd(DateTime date, int addValue) + //SqlFunc.DateValue(DateTime date, DateType dataType) + //SqlFunc.Between(object value, object start, object end) + //SqlFunc.ToInt32(object value) + //SqlFunc.ToInt64(object value) + //SqlFunc.ToDate(object value) + //SqlFunc.ToString(object value) + //SqlFunc.ToDecimal(object value) + //SqlFunc.ToGuid(object value) + //SqlFunc.ToDouble(object value) + //SqlFunc.ToBool(object value) + //SqlFunc.Substring(object value, int index, int length) + //SqlFunc.Replace(object value, string oldChar, string newChar) + //SqlFunc.Length(object value) { throw new NotImplementedException(); } + //SqlFunc.AggregateSum(object thisValue) + //SqlFunc.AggregateAvg(TResult thisValue) + //SqlFunc.AggregateMin(object thisValue) + //SqlFunc.AggregateMax(object thisValue) + //SqlFunc.AggregateCount(object thisValue) + } + public static void Select() + { + var db = GetInstance(); + db.IgnoreColumns.Add("TestId", "Student"); + var s1 = db.Queryable().Select(it => new ViewModelStudent2 { Name = it.Name, Student = it }).ToList(); + var s2 = db.Queryable().Select(it => new { id = it.Id, w = new { x = it } }).ToList(); + var s3 = db.Queryable().Select(it => new { newid = it.Id }).ToList(); + var s4 = db.Queryable().Select(it => new { newid = it.Id, obj = it }).ToList(); + var s5 = db.Queryable().Select(it => new ViewModelStudent2 { Student = it, Name = it.Name }).ToList(); + var s6 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }) + .OrderBy(st => st.Id, OrderByType.Desc) + .OrderBy((st, sc) => sc.Id, OrderByType.Desc) + .Select((st, sc) => new { Name = st.Name, SchoolId = sc.Id }).ToList(); + + + var s7 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).Select((st, sc) => sc).ToList(); + + var s8 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }) + .OrderBy((st, sc) => st.SchoolId) + .Select((st, sc) => sc) + .Take(1).ToList(); + } + private static void Sqlable() + { + var db = GetInstance(); + var join3 = db.Queryable("Student", "st") + .AddJoinInfo("School", "sh", "sh.id=st.schoolid") + .Where("st.id>@id") + .AddParameters(new { id = 1 }) + .Select("st.*").ToList(); + //SELECT st.* FROM [Student] st Left JOIN School sh ON sh.id=st.schoolid WHERE st.id>@id + } + private static void Enum() + { + var db = GetInstance(); + var list = db.Queryable().AS("Student").Where(it => it.SchoolId == SchoolEnum.HarvardUniversity).ToList(); + } + } +} diff --git a/Src/Asp.Net/OracleTest/Demos/2_Update.cs b/Src/Asp.Net/OracleTest/Demos/2_Update.cs new file mode 100644 index 000000000..2f9a678a2 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/2_Update.cs @@ -0,0 +1,63 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.Demo +{ + public class Update : DemoBase + { + public static void Init() + { + var db = GetInstance(); + var updateObj = new Student() { Id = 1, Name = "jack", SchoolId = 0, CreateTime = Convert.ToDateTime("2017-05-21 09:56:12.610") }; + var updateObjs = new List() { updateObj, new Student() { Id = 2, Name = "sun", SchoolId = 0 } }.ToArray(); + db.IgnoreColumns.Add("TestId", "Student"); + //db.MappingColumns.Add("id","dbid", "Student"); + + + //update reutrn Update Count + var t1 = db.Updateable(updateObj).ExecuteCommand(); + + //Only update Name + var t3 = db.Updateable(updateObj).UpdateColumns(it => new { it.Name }).ExecuteCommand(); + var t3_1 = db.Updateable(updateObj).UpdateColumns(it => it=="Name").ExecuteCommand(); + + + //Ignore Name and TestId + var t4 = db.Updateable(updateObj).IgnoreColumns(it => new { it.Name, it.TestId }).ExecuteCommand(); + + //Ignore Name and TestId + var t5 = db.Updateable(updateObj).IgnoreColumns(it => it == "Name" || it == "TestId").With(SqlWith.UpdLock).ExecuteCommand(); + + + //Use Lock + var t6 = db.Updateable(updateObj).With(SqlWith.UpdLock).ExecuteCommand(); + + //update List + var t7 = db.Updateable(updateObjs).ExecuteCommand(); + + //Re Set Value + var t8 = db.Updateable(updateObj) + .ReSetValue(it => it.Name == (it.Name + 1)).ExecuteCommand(); + + //Where By Expression + var t9 = db.Updateable(updateObj).Where(it => it.Id == 1).ExecuteCommand(); + + //Update By Expression Where By Expression + var t10 = db.Updateable() + .UpdateColumns(it => new Student() { Name = "a", CreateTime = DateTime.Now }) + .Where(it => it.Id == 11).ExecuteCommand(); + + //Rename + db.Updateable().AS("Student").UpdateColumns(it => new School() { Name = "jack" }).Where(it => it.Id == 1).ExecuteCommand(); + //Update Student set Name='jack' Where Id=1 + + //Column is null no update + db.Updateable(updateObj).Where(true).ExecuteCommand(); + } + } +} diff --git a/Src/Asp.Net/OracleTest/Demos/3_Insert.cs b/Src/Asp.Net/OracleTest/Demos/3_Insert.cs new file mode 100644 index 000000000..c9e52329a --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/3_Insert.cs @@ -0,0 +1,58 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.Demo +{ + public class Insert:DemoBase + { + public static void Init() + { + var db = GetInstance(); + db.IgnoreColumns.Add("TestId", "Student"); + + var insertObj = new Student() { Name = "jack", CreateTime = Convert.ToDateTime("2010-1-1"), SchoolId = 1 }; + + //Insert reutrn Insert Count + var t2 = db.Insertable(insertObj).ExecuteCommand(); + + //Insert reutrn Identity Value + var t3 = db.Insertable(insertObj).ExecuteReutrnIdentity(); + + + //Only insert Name and SchoolId + var t4 = db.Insertable(insertObj).InsertColumns(it => new { it.Name, it.SchoolId }).ExecuteReutrnIdentity(); + var t4_1 = db.Insertable(insertObj).InsertColumns(it => it=="Name"||it== "SchoolId").ExecuteReutrnIdentity(); + + + //Ignore TestId + var t5 = db.Insertable(insertObj).IgnoreColumns(it => new { it.Name, it.TestId }).ExecuteReutrnIdentity(); + + + //Ignore TestId + var t6 = db.Insertable(insertObj).IgnoreColumns(it => it == "Name" || it == "TestId").ExecuteReutrnIdentity(); + + + //Use Lock + var t8 = db.Insertable(insertObj).With(SqlWith.UpdLock).ExecuteCommand(); + + + var insertObj2 = new Student() { Name = null, CreateTime = Convert.ToDateTime("2010-1-1") }; + var t9 = db.Insertable(insertObj2).Where(true/* Is insert null */, false/*off identity*/).ExecuteCommand(); + + //Insert List + var insertObjs = new List(); + for (int i = 0; i < 1000; i++) + { + insertObjs.Add(new Student() { Name = "name" + i }); + } + var t10 = db.Insertable(insertObjs.ToArray()).InsertColumns(it => new { it.Name }).ExecuteCommand(); + + var t11 = db.Insertable(insertObjs.ToArray()).ExecuteCommand(); + } + } +} diff --git a/Src/Asp.Net/OracleTest/Demos/4_Delete.cs b/Src/Asp.Net/OracleTest/Demos/4_Delete.cs new file mode 100644 index 000000000..1276ea3ee --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/4_Delete.cs @@ -0,0 +1,33 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.Demo +{ + public class Delete:DemoBase + { + public static void Init() + { + var db = GetInstance(); + //by entity + var t1 = db.Deleteable().Where(new Student() { Id = 1 }).ExecuteCommand(); + + //use lock + var t2 = db.Deleteable().With(SqlWith.RowLock).ExecuteCommand(); + + + //by primary key + var t3 = db.Deleteable().In(1).ExecuteCommand(); + + //by primary key array + var t4 = db.Deleteable().In(new int[] { 1, 2 }).ExecuteCommand(); + + //by expression id>1 and id==1 + var t5 = db.Deleteable().Where(it => it.Id > 1).Where(it => it.Id == 1).ExecuteCommand(); + } + } +} diff --git a/Src/Asp.Net/OracleTest/Demos/5_CodeFirst.cs b/Src/Asp.Net/OracleTest/Demos/5_CodeFirst.cs new file mode 100644 index 000000000..165dfd999 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/5_CodeFirst.cs @@ -0,0 +1,53 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.Demo +{ + public class CodeTable + { + + [SugarColumn(IsNullable =false ,IsPrimaryKey =true,IsIdentity =true)] + public int Id { get; set; } + [SugarColumn(Length = 21,OldColumnName = "Name2")] + public string Name{ get; set; } + [SugarColumn(IsNullable = true,Length =10)] + public string IsOk { get; set; } + public Guid Guid { get; set; } + [SugarColumn(ColumnDataType ="int")] + public decimal Decimal { get; set; } + [SugarColumn(IsNullable = true)] + public DateTime? DateTime { get; set; } + [SugarColumn(IsNullable = true,OldColumnName = "Dob")] + public double? Dob2 { get; set; } + [SugarColumn(Length =110)] + public string A1 { get; set; } + } + public class CodeTable2 { + public int Id { get; set; } + public string Name { get; set; } + [SugarColumn(IsIgnore =true)] + public string TestId { get; set; } + } + public class CodeFirst : DemoBase + { + public static void Init() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() + { + ConnectionString = Config.ConnectionString, + DbType = DbType.SqlServer, + IsAutoCloseConnection = true, + InitKeyType = InitKeyType.Attribute + }); + + //Backup table + //db.CodeFirst.BackupTable().InitTables(typeof(CodeTable),typeof(CodeTable2)); + + //No backup table + db.CodeFirst.InitTables(typeof(CodeTable),typeof(CodeTable2)); + } + } +} diff --git a/Src/Asp.Net/OracleTest/Demos/5_DbFirst.cs b/Src/Asp.Net/OracleTest/Demos/5_DbFirst.cs new file mode 100644 index 000000000..7e79a7734 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/5_DbFirst.cs @@ -0,0 +1,72 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.Demo +{ + public class DbFirst : DemoBase + { + public static void Init() + { + var db = GetInstance(); + //Create all class + db.DbFirst.CreateClassFile("c:\\Demo\\1"); + + //Create student calsss + db.DbFirst.Where("Student").CreateClassFile("c:\\Demo\\2"); + //Where(array) + + //Mapping name + db.MappingTables.Add("ClassStudent", "Student"); + db.MappingColumns.Add("NewId", "Id", "ClassStudent"); + db.DbFirst.Where("Student").CreateClassFile("c:\\Demo\\3"); + + //Remove mapping + db.MappingTables.Clear(); + + //Create class with default value + db.DbFirst.IsCreateDefaultValue().CreateClassFile("c:\\Demo\\4", "Demo.Models"); + + + //Mapping and Attribute + db.MappingTables.Add("ClassStudent", "Student"); + db.MappingColumns.Add("NewId", "Id", "ClassStudent"); + db.DbFirst.IsCreateAttribute().Where("Student").CreateClassFile("c:\\Demo\\5"); + + + //Remove mapping + db.MappingTables.Clear(); + db.MappingColumns.Clear(); + + //Custom format,Change old to new + db.DbFirst. + SettingClassTemplate(old => + { + return old; + }) + .SettingNamespaceTemplate(old => + { + return old; + }) + .SettingPropertyDescriptionTemplate(old => + { + return @" /// + /// Desc_New:{PropertyDescription} + /// Default_New:{DefaultValue} + /// Nullable_New:{IsNullable} + /// "; + }) + .SettingPropertyTemplate(old => + { + return old; + }) + .SettingConstructorTemplate(old => + { + return old; + }) + .CreateClassFile("c:\\Demo\\6"); + } + } +} \ No newline at end of file diff --git a/Src/Asp.Net/OracleTest/Demos/6_ComplexModel.cs b/Src/Asp.Net/OracleTest/Demos/6_ComplexModel.cs new file mode 100644 index 000000000..5ca494f05 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/6_ComplexModel.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using SqlSugar; +using OrmTest.Demo; + +namespace OrmTest.Demo +{ + public class ComplexModel : DemoBase + { + public static void Init() + { + var db = GetInstance(); + var students = db.Queryable().ToList(); + if (students != null) + { + foreach (var item in students) + { + Console.WriteLine(item.SchoolName); + if (item.SchoolSingle != null) + { + Console.WriteLine(item.SchoolSingle.Name); + } + if (item.SchoolList != null) + { + Console.WriteLine(item.SchoolList.Count); + } + } + } + } + } + + [SugarTable("Student")] + public class CMStudent : ModelContext + { + public int Id { get; set; } + public string Name { get; set; } + public int SchoolId { get; set; } + + [SugarColumn(IsIgnore = true)] + public string SchoolName + { + get + { + if (this.SchoolSingle != null) + return this.SchoolSingle.Name; + else + return null; + } + } + + [SugarColumn(IsIgnore = true)] + public CMSchool SchoolSingle + { + get + { + return base.CreateMapping().Single(it => it.Id == this.SchoolId); + } + } + + [SugarColumn(IsIgnore = true)] + public List SchoolList + { + get + { + return base.CreateMapping().Where(it => it.Id == this.SchoolId).ToList(); + } + } + } + + [SugarTable("School")] + public class CMSchool + { + public int Id { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/Src/Asp.Net/OracleTest/Demos/7_Filter.cs b/Src/Asp.Net/OracleTest/Demos/7_Filter.cs new file mode 100644 index 000000000..273f6f814 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/7_Filter.cs @@ -0,0 +1,72 @@ +using OrmTest.Demo; +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.Demo +{ + public class Filter : DemoBase + { + public static void Init() + { + + + //gobal filter + var db = GetInstance1(); + + var sql = db.Queryable().ToSql(); + //SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] WHERE isDelete=0 + + var sql2 = db.Queryable((f, s) => new object[] { JoinType.Left, f.SchoolId == s.Id }).ToSql(); + //SELECT[f].[ID],[f].[SchoolId],[f].[Name],[f].[CreateTime] + //FROM[STudent] f Left JOIN School s ON([f].[SchoolId] = [s].[Id]) WHERE f.isDelete=0 + + + //Specify name filter + var sql3 = db.Queryable().Filter("query1").ToSql(); + //SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] WHERE WHERE id>@id AND isDelete=0 + + + //Specify key filter and disabled global filter + string key = "query1"; + var sql4 = db.Queryable().Filter(key,true).ToSql(); + //SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] WHERE WHERE id>@id + + } + + public static SqlSugarClient GetInstance1() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); + db.QueryFilter + .Add(new SqlFilterItem() + { + FilterValue = filterDb => + { + return new SqlFilterResult() { Sql = " isDelete=0" }; + }, + IsJoinQuery = false + }).Add(new SqlFilterItem() + { + FilterValue = filterDb => + { + return new SqlFilterResult() { Sql = " f.isDelete=0" }; + }, + IsJoinQuery = true + }) + .Add(new SqlFilterItem() + { + FilterName = "query1", + FilterValue = filterDb => + { + return new SqlFilterResult() { Sql = " id>@id", Parameters = new { id = 1 } }; + }, + IsJoinQuery = false + }); + return db; + } + } + +} diff --git a/Src/Asp.Net/OracleTest/Demos/8_JoinSql.cs b/Src/Asp.Net/OracleTest/Demos/8_JoinSql.cs new file mode 100644 index 000000000..78adb85b8 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/8_JoinSql.cs @@ -0,0 +1,51 @@ +using OrmTest.Demo; +using OrmTest.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.Demo +{ + /// + /// Secure string operations + /// + public class JoinSql : DemoBase + { + public static void Init() + { + Where(); + OrderBy(); + } + + private static void Where() + { + var db = GetInstance(); + //Parameterized processing + string value = "'jack';drop table Student"; + var list = db.Queryable().Where("name=@name", new { name = value }).ToList(); + //Nothing happened + } + + private static void OrderBy() + { + var db = GetInstance(); + //propertyName is valid + string propertyName = "Id"; + string dbColumnName = db.EntityProvider.GetDbColumnName(propertyName); + var list = db.Queryable().OrderBy(dbColumnName).ToList(); + + //propertyName is invalid + try + { + propertyName = "Id'"; + dbColumnName = db.EntityProvider.GetDbColumnName(propertyName); + var list2 = db.Queryable().OrderBy(dbColumnName).ToList(); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + } +} diff --git a/Src/Asp.Net/OracleTest/Demos/DemoBase.cs b/Src/Asp.Net/OracleTest/Demos/DemoBase.cs new file mode 100644 index 000000000..9cbda2855 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Demos/DemoBase.cs @@ -0,0 +1,23 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.Demo +{ + public class DemoBase + { + public static SqlSugarClient GetInstance() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); + db.Ado.IsEnableLogEvent = true; + db.Ado.LogEventStarting = (sql, pars) => + { + Console.WriteLine(sql + "\r\n" + db.RewritableMethods.SerializeObject(pars)); + Console.WriteLine(); + }; + return db; + } + } +} diff --git a/Src/Asp.Net/OracleTest/Models/DataTestInfo.cs b/Src/Asp.Net/OracleTest/Models/DataTestInfo.cs new file mode 100644 index 000000000..935aefaff --- /dev/null +++ b/Src/Asp.Net/OracleTest/Models/DataTestInfo.cs @@ -0,0 +1,135 @@ +using System; +using System.Linq; +using System.Text; + +namespace OrmTest.Models +{ + /// + /// + /// + public class DataTestInfo + { + public DataTestInfo(){ + + } + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public int Int1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public int? Int2 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public string String {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public decimal Decimal1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public decimal? Decimal2 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public DateTime Datetime1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public DateTime? Datetime2 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public byte[] Image1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public byte[] Image2 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public Guid Guid1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public Guid? Guid2 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public decimal Money1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public decimal? Money2 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public byte[] Varbinary1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public byte[] Varbinary2 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public double Float1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public double? Float2 {get;set;} + + } +} diff --git a/Src/Asp.Net/OracleTest/Models/DataTestInfo2.cs b/Src/Asp.Net/OracleTest/Models/DataTestInfo2.cs new file mode 100644 index 000000000..8f425a4c1 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Models/DataTestInfo2.cs @@ -0,0 +1,44 @@ +using System; +using System.Linq; +using System.Text; + +namespace OrmTest.Models +{ + /// + /// + /// + public class DataTestInfo2 + { + public DataTestInfo2(){ + + } + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public Guid PK {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:False + /// + public bool Bool1 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public bool? Bool2 {get;set;} + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + public string Text1 {get;set;} + + } +} diff --git a/Src/Asp.Net/OracleTest/Models/Enum.cs b/Src/Asp.Net/OracleTest/Models/Enum.cs new file mode 100644 index 000000000..09102a410 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Models/Enum.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.Models +{ + public enum SchoolEnum + { + HarvardUniversity = 0, + UniversityOfOxford = 1 + } + public class StudentEnum + { + public int Id { get; set; } + public SchoolEnum SchoolId { get; set; } + public string Name { get; set; } + public DateTime? CreateTime { get; set; } + [SqlSugar.SugarColumn(IsIgnore =true)] + public int TestId { get; set; } + } +} diff --git a/Src/Asp.Net/OracleTest/Models/School.cs b/Src/Asp.Net/OracleTest/Models/School.cs new file mode 100644 index 000000000..4373f3feb --- /dev/null +++ b/Src/Asp.Net/OracleTest/Models/School.cs @@ -0,0 +1,17 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.Models +{ + public class School + { + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + } +} diff --git a/Src/Asp.Net/OracleTest/Models/Student.cs b/Src/Asp.Net/OracleTest/Models/Student.cs new file mode 100644 index 000000000..421b87bcf --- /dev/null +++ b/Src/Asp.Net/OracleTest/Models/Student.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using System.Linq.Expressions; + +namespace OrmTest.Models +{ + [SugarTable("STudent")] + public class Student + { + [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "ID")] + public int Id { get; set; } + public int? SchoolId { get; set; } + public string Name { get; set; } + public DateTime? CreateTime { get; set; } + [SugarColumn(IsIgnore=true)] + public int TestId { get; set; } + } +} diff --git a/Src/Asp.Net/OracleTest/Models/ViewModelStudent.cs b/Src/Asp.Net/OracleTest/Models/ViewModelStudent.cs new file mode 100644 index 000000000..8361ef1cb --- /dev/null +++ b/Src/Asp.Net/OracleTest/Models/ViewModelStudent.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.Models +{ + public class ViewModelStudent:Student + { + + } + public class ViewModelStudent2 + { + public string Name { get; set; } + public Student Student { get; set; } + } + public class ViewModelStudent3: Student + { + public string SchoolName { get; set; } + } +} diff --git a/Src/Asp.Net/OracleTest/OracleTest.csproj b/Src/Asp.Net/OracleTest/OracleTest.csproj new file mode 100644 index 000000000..4fecf556e --- /dev/null +++ b/Src/Asp.Net/OracleTest/OracleTest.csproj @@ -0,0 +1,104 @@ + + + + + Debug + AnyCPU + {4177D054-D113-4F8A-9E01-642E072F9C87} + Exe + Properties + OracleTest + OracleTest + v4.0 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {489bb790-226c-4fad-8d1e-51d72a7ff8e5} + SqlSugar + + + + + + + + \ No newline at end of file diff --git a/Src/Asp.Net/OracleTest/OtherDll/SyntacticSugar.dll b/Src/Asp.Net/OracleTest/OtherDll/SyntacticSugar.dll new file mode 100644 index 0000000000000000000000000000000000000000..f6dec3bfb8691fe600b8f171bdb1ae0e0465d9f6 GIT binary patch literal 119808 zcmeFad7Pa^mH%J;+TUB<{P6sJM*#xT4~|LB?eqx6yINnbBc1{@$Nc&vWn7ov`TlJHJ1EuV0|+ zR@FIm>eP1XRMn|^PT%k{mvheL`TNUXoV%A_{aa=3BRksw4@`Vyz}-{+%HH?(o%WTz zpYZfeoyjZP@ulqxo-ujR1y@`VZ<)OClF9Z}S4?iYV)FPi&Y65heDNg*_V-uzO-P@4 zf^(zf9bDVMWj&pmvgIL z;M|b?-}_C19>u*6x~G~yaM!3JX8)TET#dMW!J9uD_DJDL=SmrPiSXky;RCl^a?KXP z`7b5qQdtweQ#6u1^}u$geGw6!x1_*d1vm3=m2;~OY+tfD22s2^cs5$!*bQ$@CYgDE zq6Ief{O;#6h>0<0f%KeQi3zm7P)ix%`drKVFE&2*h)7Dq%Fwka7{-A%tGp2Jt)U`O#kVf=u*S zFM6*`^xQm2q6uOiV<8&L0!L+NJl0(_sf2su1o1-LO3Q_d9px;#8^NK!*IoPN@Lma` zeSlNX{pF?ku-0k^?OTbD8Df=cagH@X0(xT5EXMm0-@Xlu!M)B1H6LrAE#cAgSVpa zNkAtHE8)$Xn!5rRQhP5gxMu&(eS(PI7FLV9gG!_QJM%SHy4IB!yFNsUdidjxa`|)c zj4#VM>O$jP^m9%1+$0C}e<~mPwVh=*THBegy5hA|m?$K4_FlMWI-`Fh9n}K^O`}8g zqd`&$88Sh%oGMx5l(%@+I4vi2LfwS$c`iu9hVO@0v$mBnk>9V89}c2}Nlp3Ybq>M9 z=-W9|WPp>ZSd0%94B4@>Uh*X_(f1EaBHhjc9c`y0=RSH@;0|~Bl@iSIFL2A(s^0Xk z&s}t}D`*ss)1S^Ih77IE68?^z#b3}lT)Y(HBlw|xa?RY$o8lFgZs$-bVXxF>FT)9$ zFt!6)Zs;c8vya^)*S`J^b&Zo8?IiwN?%?yiU;KBrc>dJ~Bui%Yft+g< zg9!N&E}|36!ci5|PiEr;4%w^mMqjepu7vT?6oE=Vh94XK>Q8~w*Do65e#ZkR+ ze8!on9LYIkgZhr@U42|LkZVO~5L6mH-b=bvlH^9?)8J`QMpAe=J>V8D>(P7xG;OZS z(!81+_7lxSImxx}W_}B!(;;YCQy_95aWeq4Dx=g##cM$Y1sx`nmJw5NxiHd%TXjJ( zLLX7Bb){nb$Hb_4AT2k2lX6eaE_ZG>YH4}rMJX-n7Fx&?^|AO&a{ty% z7m;Zt2%A0}oke7PHqN53wsXKHxgchCgwF?r& zm8POqjDFR(O06_EegdSBqQz$Db163RJG}@k)C)^{BD9`g>}AJZZsajL+jYElU{Fqi2+*jDnb!rR)YqeOZ(j{obKSKr5A( z>qwi*oV>{?Wa=!qSBh(;=EQ-wm*VxLXl_r_?1|=v49&oS@6cIQe{`nMkDOBoQK?}C zK|JWf;`V4UArv8ma1jM)SDwlH=U(fn8BPhDRu89?;<&|YptVs|5Jb!cjCjevKy@aH z%2#8Hd=pi}a2+~Xpt?wL65hap&}j4|5j1^7`s4ZF(M>Y-qIo7JT0^4dr=9r8N)u*c z8QvA&(}JcoZU;q_=_#3Ti+;i_#!pp3*oN=CgUbJDUis((C_Z9lKS|VhBxa@k0V(B- zno1@zh%cTQ5nrP4;u#6Q{kJCkpT9NX{(X;~)tetfar_uZ)}!swz9SVsGNPwZSVTou zq7*}xD3UN4iLxh6(=R&`Jz>!8cc_>Bdj-*@B({E+>OZ;QId4UYjh+r5-h|U#OXb~S zl+C^1snZHv*a%&)q#8*5m)_p$Yc@)CEjC9Q#T9*E0va`t#UqNF+kyO?a&;~f-Db5O zPCRK^xdrubSGWYCoy&nlByJ^%Ksm@zpw}oj8dVGa? z-qP*m%3eY=s`YBK9!@Ef+w0Z%8IbRH^@3p?xwf650Z`QEa(-aq)qjOTpeof%1#f+V;9om13~mP1def z$=id8qo&*72a`jnZqps}Zab^bO>dFc8q3R)g0;n@()-FZw;IG(ff!$nQ;VL3+b9p0 zcQxlw2IH#VR+5dpD>W+3Ms>yCt1c_`>h?x~N{O#gim)EW&&IQ49M83Q?ni9(MN{~q z=ipddk2Y%c8gnx!(~8^P2-}Zi96*|=twgnt)v!F(Mu^+z>Uzcl0yoj*%zW421P%mD!4q}aR-Ig~RKBanh zeY3}+6evnTa@o(@%iI&LmzeM}15VvSm96~__(-aj_H0sr;b;M8Y(U<*1M){NhLz4s za4N2I13yf2F{7*E*yFfSznzlsPf$< zi81K;TkamW+3OWr^SmDZ_7Q*4%b=8xUyhq>_p~2^W9u#&(V{m$Y}az`%IFnBx)ov7L{cST+g6Mg7pck~N; z`p~iPjn2bdYkjkVR=i|Msl7_1Volqv5NqT}0C+SkZ=Elz_WvgE*efBVXAMtc!rt25zY zh|qQ2P|ylm3p^dor<4DQ2#UAkbInHW!C&MMr_nNz9jFg1-7Cq_Fkd+X^W$JPFRMgPPUs(dj)SGP%oOE-Y9uOlZ@c!Ugme2c4O@J8I0`*W0`uo3u5h;kw?4(pITPw*F8K+ zdk4t2-4?%5jFh4`@uSYSTgI=Sk@33%6}4Bj@taAP2{+@n%#3KiMLB(1yfF=BQQKb? zM2yr+_G62m_-(VWz9)p@ZqffCiWkkoU6hC7S{%>d-hgxQ+i|U)cVplhFzbcl`o_@k zQ1lMacEfnJ2)+wvHpH~Y_?^A{t-o43d|K$)cIag4XY#95pYMvZ+pn8$%=Ww+^?JQI zarEu=`sl<`T+{O;cAxP_m(aY8+KKrp9RbO0J&&Tg3t70>L4?l}kSDSrjCyRBZZdccI+Bz|lOFdtT z-%FDCeK?u;_-=&}$35ms$l||KY-UnBsGjLz?+2Kc@bzwIagl3Qv_rUaSp40iq~-4N zF#``9Y&f}kZ85yAJ`IO|Z=r6s(uMa$-V_NF>{E|c{EP7%Nc^x6lYa~|x0<-)Gx*vI zs}j$QoYh}a`DSY!>64^QWPOm4_37SxcK=@U!JcszLZ@JKK43UIaM^~S4YbZFNVMj2 ze(7iV?hpQ=-SF8?`5-A6-nPG7tdYoX#%ax^H2lG9HV@K#Xpdf9EmGQG^d_pf zk4~A}QOw8piceouTSKwLWA{{e@rMOs1-X({=B*Qx>6t^7;G{z+-`<)pz;o>g0Dk+! zBH_s&?V`th{q~s)(vO9mk3cRhi$71AmCq^4$0(;+m57;`yuG!=0Dp0A`JjAH!DpGa z`bKBwyMA`Q@0yu!puNmw&md=tMX&5RcLOl`V0s3V^G7J?%-W481dV)ab8c)yH7~KP zs513OdsNm}+d~CJ*##=0Pt@PqpM^x(4qqyzF#af@n>Q8xU{YF5d`O7(9GF>AjNpA? z-sE2ewFLz#4>M}_ULT!=OmcqoF}w-$4~v5m`KUM_e+)Ph%-y_l?riEw1J(u91bvkb zo*${UR+)O*Kb*^Grl;LoR)=JKtAO}Z&4 zIj76pez=zx))qFIe1ej+PgHgq^|ru>W~RlQt{rJk@h4TG@5wL+XJyyEhZyOtpR-?8rsyH(6Inhh|8Co){a}ytg3&kz z8eWdiqVb)SCps;2I?tt@Q-)ia6HMIPB-4gY+OnrQ6M%xDNdh)aWn8C6B^rtkx zCA&3S7u0LpM`*T1VbU=xt@#g|iB*j1@M(MC=hN`KWUowGMYN9*-L?2E?@=12ku9ij zX6D#UmF?hrkX`C=LHrp@Pt$g%F{@L}=Nd1;6s?puwigDuX$9=8Sn#C=53_Iux^SPq zn1w4a3tq~?73jhbH2UQ%T!Aj!)30RV3e1ATX^(#ex^S4Ke6=iGfiB$V&rH@!uRs^> z(+_0f3UuK<{a_ZZz~UbyTQ@Ffuc2|H%MnH{*oPYB-|vo%o?+p65gR_lk4Dq_WyTy| zR&qyC=!4+fb#@TT$wvHH8qiMut4P($h%83W$JJ)Y(qR{bV_IE@L{uL9OF*N>|3HFN zY2{Ea$roR(6hxcB^|NQ1er_-QCrF<+n*pO_cH8_08Aul&xVd&FBAsyb^6?u z1OsiVh69D@C4$upwi|)OvyR3Bso)P#Tq)_U>sR%9X+N||6BkD}D=EvMISuSJLUzu+ zq8!;(B6cTk12M+_=Hk`!HPHNerLVcMkfx#@H=LIrQ$?V~m__L!eP_*ua{X z4vgUk&nHFatH7(pNo}S~4x+EdUn8Qnmp6W6tm#KQx-d&17hdBtt_W8yXo< zGBgCTp^*V4Lqi}N8W~VBGz7AtkpU$`Lm(R(8Bj7b1hS!#0WBychFl}j{S>P|BX=74 zMDQ?3p08?7E2t}Zh95kN<>Dhq9%p=ENOKt==Hc?BZ^6Q4GEVF z3Y)EYFSuE(Sqq#GSdsorVne;Ou~E(Yo$ayVvCP_m>N{Qh)aoJ9?+oLpUeh^1J+y)B z)t?tbi_L>%9J0~yNif?lmgIaBK8;oJslga_2V)RzAz5nDW(aeT9Iud|U>lPPYYaa) zL0LRvw(XXv?beI2{vf&<+&u#a>isuwst>U1@AKD`H@{a;pXp=6vN5>g6n#rCko_V8ktmD`(;xL5L*%59xX(@A8LB>RuI(81d8P%nEU z%{A25tR#lB+W&7(Jm+@$ulg1TsEtCi5w@1r3-wTEh}Nxr=S~-Db}E3)Ri!mYJ9XFP}+zA%K=>k**Y0JAQVa)${Q>70th8T#}`K5rBp?8JKw`g z(coF@ww$};k$Cf5Mc*e)%`;~H{+#`w0{Pzpwuy&U%GzXw70DX0TXLmJ89rKFM$I}@ zpnjLzTnUqcU`VyOS~R{No>h1)xsw=%hge%iKY%6d=6=XeHOLpjh_zf;%NIHi5Yu0d z9^^;OIu|45$DDjXxs9}`+Xwy{wNt>%gONfHy*^I@|I&7TsXu8?3S zC}Z(Ii4dLUXZr2@Gj5|edeb&E2A$qDCoaD1&aFRJ+EV8i0!q055>K;U-VyyuF_n=< zmBW_SK{{fsZI6FVWcxkpqW>a1+La?6Ogjw9?lFC>MqfjxPR=w1{!G29T`_s)$1J{a@cM(Z9k`{5!Gr|2NVjG!iw9(6E!erPW}7R`IfPz|Wu7=){M_-=Jn< zomq0PW$rvQGfo(l0dvjJQZ_@SZVUx%z;$D!cMRq7)k1BcsNZ{-*n}wk0^I(xYmd( zV~Zrl6zl0YwrE{(C@2l({3yp@x{xnK5?^khIFJ4=g1xbCcMCL@xniIJY=S^S*^2_C zPPWSxQ@Mc0%Z1`hxlriJ1?o&JC1fQj%Dw#eud^)biU_7o&@xOUBBHf-7OjcJoeJye zrc$Jsl_HfyipVmhCq=4WiZJvODN;+MNdHJ<0DVSMM9Rz_q=@Q@ktS$kKvHDpj4kkI z>I0G@@^WNEheFS&q+*1bMKSrAf&_Kebk($z`WD%}lP2-KPD*zg;%|Vz8h;2X+4^h3 zw=SnXd^i2?FyDtY03-^>>SO3)uLF?x=h8mn21TTXf&T`s*JtMr&&}wwVZ1?*1LPct zQw@vpzw^7OXj4h8WK&6h$=bTXxtv-^E0B8rZ|zC-VyW3Q0-8U(H)-t!H=$AY?RWp% zRFvNGV2ZA=58V94yrmPC%(^c-FS2DMvcXk&#!}VeM?;QYgzW@4&n}|p{w2yd>B6jc4jp4@sR)>CAY4`|z zI4OS4j~_N}IL(e;z#wjvnr4MJQE60zs7;JlEE+1^KB%a}rLJ&gnNH{@^cV@&id*qA zs?R4%>;jdjMyICtS3%%1mXRDYUByU_W=Phn>r=#&J>uLMh$7R?QOHo7+%5eq3@Sm! zgbCXTzory6n_f_Ov9U){UQ4<#+F7Ox_xmn9P_HFjcp&M*gCmWhW}~hyJXo*qsSB$@ z=)!_FhSY`YbYZ6L`k-}Tfj?6pQWuujci|!O`764x&IL}UA&yZ0HANMDxxdM|=pw3b zy9`Ws(PX*qT1bbgd9I#}q0GSz6NR^TRQy*)WME+Tv(h_AD{NfY7D&a7c90U4nkmYK z%Q_evRH`LkE5#jQK4^ayIT+nYH!AruB$Eyo$odzd#@h_UWizf`Y3#|SOtZ<+C%Asp zQoHx`0b-8yV{sXI*>P`S#SUUw0@^_1?#*g((b_`Uj>czKaacz@OZYR5{_HYf(a$HR z1NM8M`65O4Hywg{J~we9~p^WKKbmKVc`inmmu>Q-Kf zsZ*~^9anpzx|6|V66RL1pF~Tlmnh1&229% zDtuHoZ+IEozo=;f~^{PiVI~cNE8Re$%xGRnfC!o*l)kK}A}hp5O5-zY26u^)${$ z$onYe%~mw?PD_{BTFJ%G8F20b>J;0T-!AV-pA`Ty9m9c){AHr zB1T@Tp{S;Cde+g^pqSepZ_@}jwGm}aMx8_c0&Xh%v`MIyw`|(04=yF=)LQH!%!(pE!njd&Tm#L4dD z%>0qt!qmJVc9}OyTNhBfwku{EVhuKoie}$!IY`~ChsGURs0Tz?%~eL?3a)q>Le`_( zCo>OZSDq{LYBZv%VRR=0R8c{5K;2F@pV`m27DWNG6K3|Adw4IS25;j}Yk_kRN+*tN zQzvL|XJl*>!`5y?o6K@i=sYWE1yU*W##06*~{&YM|Yj3?tQXU5QyHM`^a zzUF(o5`f^$$CLTW==3(rEzQrZn8yLu8Pq zSdI>(*Ky6uaJ_Mk=CuH;yT!?!yt8#bFqlHUs!WV*h({pc79Xz2!rW+%g-j1U6uwrA zucSIERySe(M%BoO9eY-X`wE+*CTX^g;tb?R;xQwjbr_sHe0p{r5Ga+|1PUpEvuD=u zT&U`vtm^A|&|TAQ0~W*c09HHfv@?GUI?T1_wO(r6SHc{&) zcI5lI{ZBPfNqYtE6!JZue51vrj9WOt)Dql727@W2OJ!o0%`9xP(o?EIb6Sx>rPXM5 z4#ZapgQKr!g0=|PZ!6zg#YW5% zf;pBAnz;s+HP!TTe67V;ZB5DNTZ`GUGJPY!I+)2c8UR^?+J(OVq#iCt;^%%~c}L5c9T zOYQd|WpZ}iz+}F$f&|j=^tW_0mYMGZw}dq4$c*%`E~EArfux?-khrrxPs(nnipeZc3vOc zJuhz^t2F554y`tOR*~iNh~3Io+lLhP&jgidNEiC6Xe8FTO1n2{ZSI$SBl^>Tuhw{l zN{!VS8zfktnF*h@9aF+1;OBE$T+U$JTC0!Fks_BZ*vj1sR&E-W7r&Ml`r%)ZzH4%9 zY1LoOP~Ka)12r@2qjt+W-|H`bUAkU7PLSW3%CB>@@(b>?-0SW7`)@b-pjS zXFVLQX#nvm5+?1NbAJZ^Y{S2au7onS+Dc%@JLniIzYpBqj{q6>SHi9aONVN@o7b95 zF6M=HbE;&zM!W_Btd(}VEw}U=&HmQ4&ZY(KjU^d$>j3E%IV)H&^>}Daos46}4W>AAuEeLxVXvfOTBLPRt&Oii?_uoLJEs9x zj=}Wl_!2d?SE1FOSBK!0&RVe8Bq>b^Jw8Lub;NTMlKoJs)lZX5J4};a-_4IS!p@l> z>Zq<>nm!9}z1W;So8J|;sQs8Dm$FT_D?Ep&&J%=c$A0zs(Rug~T4s*3)}b#> zDS7-voM;`+(%~6#3}~GV%7$!$NxJTzC7Own>Xy{-enxF{o$-{=PK${4P>I)*1uX-; zm1|A!%%^&1#VY`U{Dp&PbbyN20XR654j>jv?1>~3ao8x+q-C=K(zK^JxI|k}8m|x# z);f(T#XUj&e)g4pu71Z1h{~d%d0BD`B$dk=U)twB*V1)1z;k9^4s^%dohMkYO}Q5i z)|)kcy!1-t;w-#DXEp`1v3v6#Iw`!;LdemALlhR0m9v${-y`?3HiJ`k{wbl1jMW^v zZg*PA4DRz|iKIL8_#BH=Xi7y05#pFy>B`eK~i1QUQ zibZF9vC;?m8%L!gUZQ|QuS@N#_ktEWsrug2M2kc8AeX^SP)!EW6?ONYx#m((mo94F zj~3vs=ibknJn&Na>A<2*INO9parHBG8IJja_;S4QW}M2%P`6;IE=k$Y8J{7jc$6Km z0^Pk5tMjQVvTy~uaIee7S-1jSv8q1*+CHau1z4wPm4Weyuu-s{$#0@{to0^;bglt( z=%@{(x`K+;1*I(BF*jrhB$Du zb1J)AHCk)UA*?ZP;jtQ`scHL$YIkI%d#dQsqRffv?1T7CbBdl#1Wye0WgvZ7NN^+D z0OQfMpyhhr=x4B%3}53}{YQNiy6wFvkKH>R?Cbe^Q#1H^r$)L!_}o~rei+nBCqTf? z$t55k#~(_sEgUcBw{^{6U^bnw3P+XomsML^h(ckl5T&2>6SY}58`gofHti|DfW-xu zaj1S&Hm2I*fHtz;AcSgbFM`&@J~&9wn$8DZaq)TGh0-*&66B|OK*+C;{JP4IWx-N; z2MKT2Arvh*&ZfU1#y49vZXp^YJnbboEvC0&V>? z`H@epxV$oXz`5tXIoyyT7hg|;bzMM@Ui<)RSn$<%hiMbY7V4(7bhslh~DlKxlopkszH%U(H-g98t&iv}S z65rEpL0984nEC+FB@1%#ABc!Q2_YY4UK^a<30dRwxujz^px!x#Cqina+_aKAb~X4( z>Q6gANdF7zb^hH<_AUgD{)HSWVQE)*tezKnDYXzGVp@8~s#Ps687Rg#5=V{kzxI1Y zh}XozlJOY*Mx)Rb&ET&$)NWE$=cjMxM|$JTc~d~EmTtTsYr;tTWY0DEZ`lBPL>iejEYOy}jWWtFZq*lo=B zmyu`s)+*cJWgg75jxyAjYu`aF+j|q0&MQb)?c9o63v%eXzqOuQ^qYc}75hU8D~o-A z_q$GjDyoiC*3qfPVlH;lPKjy11Dd1JD?zk^#((q}<@Ub-m>9}H{v=4b$AsZ)G1jh> z;p^OnFt#Fglv`Lx z10?;ERTnGFe0-P3toV&mFjsz23${UQVP@==mKw7{o;S1%d}n}sdY|7O7xfW)56vbh8-$oVa4Bp zf%(@P3CX;a1mTil|Jy#0*0GmMBtF<S8>o~4GgjP=gja@W%7QhsM7j^8Byfvr4-RWwy!*wsX0b=zq~_n~QM z|4yq`jbHqUuUfs8!(zm3)_AcV&Jl3?V9L5%Z*JdAY-qB)y+d8~bVgpa{jOf@2h&*Q zNs0Wf*$lm#>gppO+x+X#WodmZO%=VFQfN{W`hMY`L;__#fi6ALiXxSMdZ}u~_??g}nd`M1O{#2`_os%&qwDq?%KIvpCB5eOQ{WploBH>c zF_;VT9FMoJq=q;cFYGAJZErRIyaE6G@s8qn`+AG98%h)Po-Fm%WV*~Gbg!`b&nXvMLNm1!&HZ`1Zyl3I=kbYtB1Ckh z-7^ej`z>wc*|AjP(#R#B>zr8tz_lyFOL`-nYR!!{b_1B%v%L&-LF7*UH?pY3Z@Ru!WHPka|S;o z3s+zk93kJMufQz$VOh8W!2P+d=(j&k0a-h~i!R2`yVa@RgOfBl?NM+qrvBQhKfjQ% zJul4FG?^`F_}}=wr0GtBEL4wh_OOA6Ze2<#OY;X4WIZ0Xl5Rxo?S=$Z(Tv8 z*Kk?AKan${tw#{kJ8+(bG3h#gCti;Psr^Uz+O`s3r%EBVi4ztyMTer>oU@*W}^ACpJRsjY|TMKx7?i2Ec z9%neT?iYWOI8HYDyF1cLzq50s-rw7W?(gbDzCt*sxRW$A!w4Jlz0K;>CV+>@%7FAL zc(RXO>4M7GQk>@XBl?;{)pPq%ukdOAq#ykqf7|)vh+#%N?d~oj?$S(rR^E*Qm%L-^ zLgOiz`Uq7sV~-@zd$W&-qkhtY{#DT71;~*`sdEZ4P6}dfTJ-2Vq1D2EjVcw0;GiCw zjY7AH3fU&&B2m4L&UC8eEZ)c5NB;q2`e-xhqn*zwOM0R`i`%G>t6lgL z*I0dbb7l3Yw|)a&R=DzZ-(=Fk9%}Sivr4C}!?ffcI?UQCqW$yY&~}bB_vEym(LFe1 zg@$^?#!&nPko<6pzlc|l^rLz0PnDN^kJp4;4Y6?DPvepIh7zD%HxrO0^TcHQC1nVxId+r030!C=EEA{w#wNi$uv1cDZMOBd$^aW z=TlG5vU>U|oONaDagwQDBPJ_TXJFJ^=YHVZ6!|dnQ=r-M^T5?!eqM$i@O9wvH*ok` zM@icEH$_W#w1S?!QWh=#76_ilURwt}8>roIvo=uP&g2@(+OwJnroIhD*_nKY-`(s? z6zT0uzKc(GCg0k9afW#1coi>ur;|D zTa)KvFQTl7^f~luCjJ5O@egsPAHc!JM2M}!K~&fdIj0}Qr=HCDDQW7RT%7)q{152tMRT3leAAokiVE$K)q_Oa%9z-z_rJci7W+Lk zDZv~{ML@0ih9N8+DAYDQH2 zQ^i2a^c41%-L=r7=w?C{Ga)e$*ePItgoQH8*MAazV&g?q{LFs_17Ghm7-{_sxQV5y z&JpO`RNs)$nb-t0Y(2sXv}d9vOZA07`dh=p+{3`flT)Q6Lt^$N#&+|5%(9oKvtXmU z?4NBCc zm2ypsk7!b$3nlZr_Hxfb+xjJ0<>FuAR_#?(%>Wm<`z5RFJh6Aim_7k)HM^G^40dr~ zM8(e4Pz!Q}VkwM%4IM_p-rhWg-4rkMRuMfDMQ_}QzfV5`e=FYxa3+haYWE>KW1(Ce z$jASp4AYBh;+@z+{2Rsozg-;4lT%&0t=4zFfZH2xVe{?$3~|IH=9g9r@o!-eT|`^m zm}3;;e35U z{#!gUw>`w~w46Q9ZT};*?%ehn^7C_>2<>@pyQWp}mz(BH3rSOy$j_?A_)m&sN^DL4 zIl}_xlR?Cjo(w@h z-v#o|nD6ercji3Abj^Gw+K)8fDW^xA?<~_tpYOW)^yWK}4tgy*tp;6u8B?4AtZ-QY zp7w3cWzU0m=CY)1XEdvg#V3Muo%(i0_IdBD{%w+v+FRm^cJ{`5iwso#d&wuG9ChOd zm=~7CIBzxV<^2EVJjhz#0=E&nx0%gRz)SfPqbbjIp0G{UN34 z4%z81ng7P!-beN3KQ=p)`OnJ=>kXL5Y9{hCou;kc95+*6g45o zG^daEKj^9XU}AV$IR#OH)|y7$;>y_{nZ2hUZ?U0bPnLIV8o2^~G<~Xmo71ecNp>lc z4CN+T0_RLt+M7F^HSYDj@^p8ynRZq#0G8}IjaIq(9&&KBNK%x|K{g8POCl5H-U@7I zFeNs%9@VUMw40dJmqiY6#fjDHq9WYYhJ%SSq7pvCpvg;dnGjSxwRsrHDeZmeyej#g zXkE~w6+bpweBcc}RzXvB%boTLdD`<<{lR|Lju_-uiR*nHA&OK-VRvtMbm~^@eex`M%idzUZ`pHK7sE%po0*=g z9YgN_#owXS|1iJ$7w{*&mzs2^Wa8D=&mexC+6k+>!?^2b6_K;+^YJi6NF%;QZ6y(E zp17gn@qW`f-5UHRKulwa->@r>5y6KfGeey#xfhCdGy=9Nz;(FD#j1gxcd*MdPp=`( zBjq+a8gs3SoUE^T%rP=Sh<_saN*3PUcL|a^8FhE^2EWdbu67d{zsUF)SDSMkG#Z8I zrp}m{2`3J=f<XxKrO}3kU>Y2G+6l( z5<1&utvS93HV?}2I8J5~jOWh`w@WpSF)y-WPU6}sp=4XC$rI+?SpS51)C*stRD8GK z;XcUcKeZq+)m!zYZz%cwucO=*@9z|^e^Ed6$;~l*I+}?}A;2CQ#^q!=vHYdCktNPBB25U)Yvz_IyQJC%hWus+#psIA4 z=N#tRi=kFD^FIGNo}E1K{h1OUg25a>vR*Gn${zhrm_yZj7KBJNo6s>2M`**t5#pP1 zHXvp_H`oYs^jKw_{3IFk48a)LC*{o9j<-pzc!9c^H*?qgtvUY&)o`C5TvX zwiw;MUuc-;VxEw=~h&I%&GNm4AZ7?GBH2*F&Fi4zU^Z^(2Mzuk2!H} zmk!gt=sdX>bEl7aPcKHo7o4Ga`U*vS799D99gVkEn|lO>_;g~ETd#Uk><- zZxX@K8QwcL;f>gNwAk@JmKOkZpC(*dZ2u>eccA-4!i_LYiYAC0N3r7J@mY1!C{7lFX8!D^HNdZT+Pf3V=L=Wh_d{-t6; zI{R#yaNlE)34c9Kn&a$W?FIPnEPA=5@iFB&ZgH>HA5I&iNI7roS$KZdwEpzswANWO8xl8Il|OQ)ROMT&ZYfJ48PSwRxv!2+jn%Hj zhi1ZuWj7~ym#L;MhcU_3-u5j!MDL`7icr4A!0XknHSnnh4>ruu?fDLkEuUN-v4`f zVxgKTo6SIvDbGH88}HS<`b_2{KUNeUOg$~zwhCn0Hj8&@7Egf;UfwYeIHrm09mIAO zl_Xk9)z^ZF1EamY$TJI4UMEgOIXfBpxGwt{w0x!ie$)Ve7F2F-j}9U&U*Cz4!<8yi zNo$fG!HF~P#OAlh1}!E~1V{GOD4D5#)3wHDT#1}Pj&C;`sk3-)^|L5UT6;B1J9r3X zIk|Ng$db)ZrEIU6S++`^J-3CFsCNJ7NNlH9xv`t7B7_`nqQn(OQR)g~H+@ENnz4fT zU?}fk&!rR{;(gJf{PvdmjeS@;J$ z7W|{2zg_gZZ_2T#DY(K=pY9FrgHmQ{-CvXM>5nDfOu05bI=;Uv^*ZA-+fjH5$9I&< zNR_)@&t;!-yIt$gB2A`9e4B~25YLE>9Wunn+}hJ*JRToGO=^ck&6F&;=eg373XgB; zL*cwN%;Q^H>b7`zcr1nN--Sd5;fbDgwUT|WSv_ZE8@uOX@+k7+bVoOHF-2_!b+fU- zN`m2&yPri>a=X3E1h_@Pcm>?qAO%-?#Rdk%>#2v%l}wvFWIZwD_aXG0Vf#fCXh*#< z+J33`jJ0p^p1JK?y=PwgHt!j4zs`H+x9{|x1?@L_&tC1fde20;{m#T!X}>q|Rom}R ze6{w65?_D&qls^z{fWdk*#3<7Rs07Ff}7B2`fAPo6|A?|JDaFZ4A{;^V(rLAF-~*zSh2 zl{>iWP_OqsU^cD3RjSu_h0m0t^*B-}gH~hEwh!uqW>Bg(mm0i(uIJC`XQ94h;cnM> z^YwxKZ+3q&Xn&r@wc7_v=LPnKEFb9S`(W%eB=-{h^#DGSfhK=51pPPYs4Cog6@#4d;Za7{ zZ4+j?{>o{;+THoE^<^clQsTW?Gnma=vT=*$$Wd^e{Jf2~j%7>D@r%GCmp(7kL2}z?{|< zKlaR}w&OW{qsguA(#AZX{SA1CxH(sej>T#Jj^I3Fx%UhXY4mRyujwDmis?{ZhB}-Z zI4iiRe*s%d7jawj60FiM<<{0FEDkSc_x>4J)yJH~Jrhgo4qH!GVTJfCcMY~h*OLDl zY~qi1Cvb9p5-;?ejCKF1?li8@uH{VOOx`0oo3}8Yz+K?;cw1{7ZwqX2*G?Q`AN}0# z{x+TbE*1F6@>d7Crt0^VsenzgPJ8oJA_u%qD(>;60DekJMi zJqVglHU5|M2gxfY2r{_iTqMs61PwpQ`%5Hffys;`o)0JO4yDEDeGNrQQtTVl?2)2= zj(`=tWDw7Bc*@c7GYT#mV`=_+vjN5eOKON#G~sA2^gMd)Uiq+FGJ~@>bvg6p+Pj-( z$v_abs8Q(m3Py4jP8N3_pDmN59n+VUY{s;eyR2b^`WSc#7tpca%nY5SjTW#Q|4>B9 z)2>*%n+Eo}`79yL8?9Y@nbExRoI=gphj{yko~P7YzGmOmn|g{rCI%RJf1-h^FONP>L)Aijqt+HYyN$VOg5+so;< zD7}3My%OBK$(vuX;yp}rDY`089&y^kv$_7sqhjY|n2WJ|M;&0Lu}(s|p4Y5LqHpb1dYA(&j4)!TS&Ywh&LrGsO2|4*aO&RFebM{HG4%xoT{LUsd z%aYTD7TDyl7@?^PQhY|hysz$gU(@q$H}5fQc0R+T-dYi0EavSyCngU&XAn0naH>tG z$Y)w^mU3cld{!^ijExRowzFIVy9?r(@q3h5!=;8464hA4B^)&4vqi=+4f<5c(k~(~w)nSg$_nd}$%k434jOjBMd`#gL6w2B(t$2;y1*B1Va@}SRroKy| z(mi5J0M7pwuI@|R#~Om!F1;_YMJtIi8~bfZfoXA5@PfrIgRnjLq`lJftAZ{^Ts32+ zq3atSRn^`KqOS3V+_0#uU~7^yVvbA0B}4ucB$pO@)f z`Y)S7KM#Ef+?HgZ-#ulZ`1G>Iv$`4h%NnyY*fAr6Hv)E@b7^xd9Qmp>&$6}_@|~1^ zy;t2ik9e*(JdvML%wd~`UOz*R^P76j6iyZK{xFyCtOpvibVK`R_iLkhg6LKli=X6U z3-S5c*e54}R|$n9NfI_=P9e#o;Q8R?S@__I%9s#!-^wq?kMY~>w|x)2 zGQQjUpE7};BMji}tK@&T`I|awCvLg}b+=feRKA=il?fZkOxQ?e!bUC=HnN$pu_3*< zU}tpihJV&gP1Xz;Z#D9^(rFY5OZ35((IGx#*?tLJdT!!(z+=pLLS<25)PG_^LxfLW z4duL*iGuT7F29jGE9WoGg{_>K^DM!Kg65dns)f<@wZizia9N=+Z+(juVtIXkVf^3% zajk$41mw#Z(j1sDMC#arrDBTyNAD(kHsJ~(E{ATasrYU1mLl!PX99if`-t_gV;Ahm z)SsrtFQma1`O8&enJ4iJ?f0rR=sc{ITKa%M``?Hd$a|BG7$q1$xlvldb~dB9ULtQ< zk0j!Ap;BBssqb@GM(r=)k2qaP&G=gD!B}9sDEe4av;7Sa^tsakKK@o4Yd80{;M^oV zar4?seB5|1Zobh4XqT50b}oKytQ7c~}wrM%}(`r5pVVaueO#9d-<6m|Y z?25bhs6Qrc_ZHuxXh2tRjqQ6-Y5xevPTt%9uHZx6V16ON3XX?16`bDUn??a4c;!vPV~BA0N=I%z z5%K$c`puTBrCabsfL+FKUkjPU`z5?dZto&DGdb`#ux};Zs6HL(A1Cm}2yY|^e~^6< zJ}TypomdX|cMQ=One~Y)QN5^tGTw&iTRlaQ zVtAQvQlM&5^29dtJMOS*-=Oc;e$V4>lOw+Br^q>&@~)b}9_}G^hXKY_%9M2)Lp$8cp%rUw$(ShjBh9JcHa2-vp(Z#c4!s$n+pN z_0yW^%kcRD<8z)raG?`6+hhBP&w}_Yh|j{@0?uq^weOr|R^cAA`Bs}ginzYA;9s!G zMSQIZqlszb*?8s4v}wtecrXYt#p!X%f#J@jiyYSt=cr_lj!Z$4w|Df4>;STqOBByH!xD}g#h>H zT*m!Ds^?-d#n9*Tx>w^ql<5!3{}i8pen*-2SROkM%Z!J^a@op_pZkdXEZ>bECL?$6 ztopbjsgHOY#Qq9~4o)g1hUg9TeY7uHkhb^Eh5y<^ z&b~0>H(`uZ!)ZeQJn?3qOz=1+9t@>Dan!cwBfKVu2Atb=y?om^YTfn%eEu9`Bk4b4 z{m7an+3tLSY9qX#uAe;O`$8hFQqZoZnF71C6Z#DJ|&25 zfGVZrYjbe#?*wOU#$J+5qX2WE-<$myW$R96x&nv-*nSJcQCDlVF8`qXzcc?nl!br$ zuF^F=U`^eI<#$w9SG8V$F_f+EuiB!Y-@muE%tikUA>SK4Y+)BR zCCa0|XquH56UopNUe z`^6}NMI&QONgswJcp77Akwr^C2lfkwC! zOIs=s(fbuuM_PsKmFe@`Grn!Uj#_;Rf1_l6PBQKo0IBTzI|_Zl)AfgQ=Uda0O<;Z^^SaT);dcc`;fYa$axhg zI)X7fDQRU(wM0kOp+Wg?sUSj^@Ym{tf`rsIs3GoNO+s?-?n8Qm9Z|RonQWR|x|hOh z&$k&iUFfwGP3y><*%+AI3Z@j9i(dl{AA`j0mTw+8%)r@hIIj~mfBL@&F*f}M)tCA1 z>iX{J`fl&~Uf1=ph}9cX;sNUpc=7-IlHR-fm%|Qm^n7S^GW+Dq;u8&=1-@0$4KCE^3>9($-XkGpETG#duqzUGtCYWho5^rB5zt5>J zW!fLD^~!FOhwTTb3g4dGYw0xsfnKu{c!L_pTADzwclc&jCEE@~((F6{O0}ZAVTh^L zNg65aH4=hFjX@L7Y>NJ}ZwOwuwst5b&5&-&P#)y-BNY!gAVV-C-#x7mzZ2q8z=O%;WbM2R1|*Ywhju%h8|ufRZp# z6yo;^?|nFY8~udgW^}i_dZHXvDt%8=1}6M()-ZN`uz?8$PlEZ)OTadTJm6y}%iPH}se*eFlxuD!RN)viRdQCsmA`ogT7%k8f$;>fLLM{dy- zWXPB7w@1>>JtzHe((gGLfRlk{eIVsTm~%%v?-w(Jjt@)%uQcn`gik)NN{H#uKI6pe zlgYFwzQ3ghAqUfnD)EK;L&;hPE}ZAB)A63!?wCREDLRMCa~C1aS7}X}iIN^XPtulq zgG%PSHmv-MkR0CC{b(8{ZM~OoJxyzNzpF21pi)Ih9(xDv<@^q+&iJQz1{QXjyw||5 z#*6+beja$6`C~ypBmRSgYrsF9iMR6(;*dwuNi{R_Hm?27oZpawXG7jY?xBur93%wM z2k_5y$h&y*;mti=v-(aJ{KMhD_Jh|9d5!Z6F%aq48Y>uL46(>U*_4A zqz?|eiRGSts@ZCu9wncX$S0WkETnS&*)&s~{cQf&aPqS6a$kc^=N}+Lx$kET`hB;Y zU89=*9P#0l+>z+>xPB?P#`!H~ZM!$4blZQdeX#lG_NbWRzN0*^y~ZFB{jlO+l+TZu z`cL)F2{23k0<=3{#EDk0ZmhN}^2^;wv_b#X$g~pRduAEG0`8;L!~Y3R-X1WxUv>3W zvf5K!eU128#iAx=6zi~A@UM5_^pv#N-|R-Byv{7P)(&Gy+Yk0}BM8*wjl=KYP1Z1v z1t+iX!?~}kJl`cHS0Sgr$8YB5TX9Me{x)60Hd10v!2R;?1L(CD*8miW?vq5SwMFumvKY>0$>+R% zi-gU0T~3UD4B2Fn3znpVc98gl$%1;(n_sZj)x4}&-t0)F5n|&fB(?n0R4cF4H#HX2 z!$(TU*}iU3ckeCw_iom@BVOP?KdJX_Zu_|RuQ}(GHGPg*g@2l_uRip^Wd|Oz?2zR& zH#(fXne;E{M*D2#U8b1B1t#Ww&e_u5bj76|VSMjX&OM%;&3(>2$4yeXnyU6W>D-eg zGnWy5*+1&mVK1W6R$$m)Rsu4Y*~* zVNav9YCET-Pvh_1{LSG{=>!vTg@LW&)Qr6DoF`L_tM<;xzN4R+}Gh&+$VE) z6LVvJTRwE>7EUb;xU<8P!qB}o+=~0@@cP`adno)Z{>h@!z8$yeK2&;5X~6wQ<)m<) zJF>dCI?o+r?yc45R73Zn!L8wdJ7h@bF(=@L?kPh``#N*qXYT%W#T?U6E*~AaV`RXs zopTbY*5iimX>+d6&2taV5#=pSxo^M?-2+YGUpy+#=Zy#B6?c@m=Z~L-e;T*xHY_-0 zLFn$D6#YXNE?gM8b+{FG!lJuLbs=uk-LUAni<<5oxS=aV-`&6I=9qg(G{Jk3=SQOd z%;>D~VfU&?W#4{)V!qzGn|1IJOUIUmZqYJPKHA(3=04lpSD5=wb3bS9kIj8(nNkfb zmpgyC(jI2+=H+KE58Z2)zhL=j-@Dipr8br;mmlI*+<%+DcCgB_(A@paJ^Wy`*UJt# zwGg`J5HsN3aIos_)bjX=Z%M{TpvG7_~VB!TsZ6&9sb*J*qwwM zx~mSq@bF=Gi^Y8V@K50XskuW({2Bk^BNTHa{=M7I$W3i$_c2V8T7%Kn5E;_xZvZZh}k6{?xr4EhKBA>Tw0&e|hY8#f%OKK87Y&!KnS zv+{K-=eeEc?lO1L7r~(5)V`x;k2X9(c6+|H`8^Ue2|cw)tOi^o56q?rpfIy3Zf29`X~5 z`R&mf3-=xS0{Ty7)%CfB?kTH|T@|{w;2(DVt5xUGYSCY_`qVB=%j&@n(mn=y{7bs;0DyW(7p2{mF_bqNmjHUull(Ux8iO(MdSB1=6>4T zU!S5;{Ga9yo+{|#Q`Ni9K2@c->(m=h4c#a4H{C6#Y5d-0ZvOOB7Btfzwx= z-gKKS=1b=Olf|!IyXKIlyK1e<_~y0hs~<7<8|MCTt#TPSL+&DTk1%)J84DLS-N(*Q zj%S@IcaynqHTOffm%1OG$({e4TIW)0qo(_%LH}%S{VbCzXI;;BjhEAM_1_TF(EiLb z@;{Hz;T8(G2`Jd97Am+k7TTDE9&e#dN$529Je2mUlF-=(dtMTHvW0F+LYKLKDdM$o zP=@v^m@|glU4#nEBCjyayA5+bH?x%cCkchjHt(_=zGkpVPPdicPm<8rjLLr*m4)ty zmag2V672_$@@w!{CiE+VO&V+|AyHXsq2=yB40e1H`h$f|x6lzT-zQ!+5Ms7){T901 zLaW?d3q8j$*SP&HbfbmVxcB>4A(H^k#lhEfabfG)7 zPnp^m$~F9&CAgu%-e_ZEZQYp`qG`!leu z?ju%O79(J8bDuEGpBU!z-RCU7f49(!+_(GsCWl-hw?Aj!FLK{E%nBiW-{*l0%^Tcr zth96J&t=}~dB}3O%X-1Bgj8n>E!}I`M;D(5fmx^TRj8yPx7uLaU4LNpVxc$j_EoP2 z-{ck>>{5fhl~9fv{4FYIfxBBRsXOkgC^!XfAuSEm#}*vr++o2x2nq8WjKqRVL!Vlu z(0hRk_8kko&mA5-pU`(#3-)(zMWDs+zpPQ{{e*=1v*Q%{fIG%u6_mPy`=DFpVHUdA zotVM=uzS3PRQ2vuKJCu4kT1~}-BT>IhOL4E`!N?;=v)hZ#ci_C zCJWu~Hd{z<=oZihudtBk^V^&vt0wMeW8kphJFcC9rJ>KBrgYzRTMXuN|DL z`@Va&g>F7ep&z;_3w_Q)54f!s3ebWJ?m>5*g;rZ=r+YzAcL(GTVVoWw-l@@Q?s2$% z?k83CilFvq+{v2!$C$gZCg`;J?=<(*tS$Q7k1c+e`N#XA7Jd`=ylp@1Zv^LU`?0zI zZ0@gd``m|kpR>>1KOoA#G&eUW|NKGac(D0T!)?0z2G<8o_hbBZ_ou-Ng5?;H975mR zwt8T=?%s#n=kBgwo9lC5WtXnc{i05ZlH9Kv{!;F|ZP%K+&D`Tc#T;Yqi!J6B+&=f} zVbQSveZt(Y zTg*@AycFo~<~-CFx?Se4H-#CQ%QR1^|Iida$Bcd)KEFLGK7VU&IQHN9v^G|ZRSM^A zJKEgU=04usGt7O0xf{*B#N18h#<+cMY_4)Sbgn3$WA2p}bIaVrfF3qaIH%4N^kQ?L zZSD`}-9)_Hl!up({}vuzi@V%CF#h}hhqgBXkFq-3fX_KInXF`GNl1W%RVuQC#Q*`b zk^~Y6B&Z;o44HupOfq3+0t75g6cH7x2!aYq(6~@gfl@0it)RG|)C$@vE?ThNkZt0m?ZGsg*jR?TZ6q<%_d&9MIB9#2M|~5;(+@$S<(Ez; zxpr%9-Hff6Z5Lli@>k0VEu%imu!%u4zX4LNZQ{P!*JlQ>_h=3oSec2TOso?xT9QzD z&lz?GYYD5^kVU#JqNgD)lwPZil~q;;do!f%O-eL$&1|HSB5YLXjyRGVCN+mUzyv|FJF> z1I1axJ^>pfa);?qez3anm8kk4^J1QP*s$0LH@+6|S&(_faFK(Z8cJv1h-&PT(7ugk z^KtgI+OWaUjS-!OjRM2hIfiS?31H*JYlck&yI2hVnbs}9llF;Xtzk|Xy^2AZYejQON^2Ko4-a#Io1S=4^ zh8+hh6t#xE3RWc68}>fZSuDN`vR{f4an(gSlrylLF18x>E!Yh4l3~hLiZ6&nkJOfN zU=^akuwGy@MZIBtZEcuipEYcl?RI=|WGZc2iFK)?ZQJnmk!)rgQzwpp4WBnG)w-yw zY`dY;f6qiLvF+``e#>u(lJ=R1M%xqoTu!r9wxjrpiT-;g;z8T<{0$nd+h;o&#vVuP zv_GbGkK0}iu^z_|%6w77X<5tZyh5yJwnhBS_7V1y504>#Tku8F&#_L}o~>E0$ZtiB z$Q>JC7U>jUGTSJIM8?Q^aS7(BfxNp!39~I?bYwNY<#M@UQz8@PQV}(gEH_3~MD~%5 zVgNH;W{v#+8!7g>$Slz)%2~HX_`vWL7{jiQ%#ux_-LTD(!=zWdV%R;A7fHW}#IA54 zEz3nBvn}FKvQYk995?J8ShkAK z4EqeMP4vV(ocw(cc8$m}EIKMnTq_nB)(dQ{IAqvGVAqLM%-G4_q^Rj~ow!`HsFJ8T z@*h|p;Qp_@}6S`lD%MJT1dYQaMcnph(X$D(qSl<|jyj9#{ z*r=G3SfSlvSP^s^#iNGJhi;>I+_0vYRq{6RXTz?ESp)W(VVh%?$xY%@!#WV(Ch?77 z2jFkBNGQ!xQ1GI}EpnTn zbEGIUkrBI9-YpW#H7km}Tka5h44VmdueiKI>n@FbK;AF*%nYzc__rhkriZL$YWw0vvpBtdaRN!h#7``-(w9}wPDfm4tZQGHLO?s zNj#PI8EQ454KjbsIAbQ6x$4Y5dKbz4$b)9zAW}I+ah))T&P|a z$AfGP*hhx_F(F62BBHLO7`BK%CKP}TX0{QmLj6VL8TLU!7FMpUhJ6X$Yhqyyr;Ou! zT~spDqs;4K39~k%TgmL1DC+fJ7wwt}8du&B#|@)#OIlJ4sY;BMbJTSQ~xCiSVPG;DR^9qKc&KFID?XT%}H z)+XMkz7Y7Z82ekB_>lTiShTWI=YxS*oEyxb4??lfXclVzu2?2d`7 z+bI0`(aHVf2E!f%>n}Uma$VFFNsBB4@|3aR|ht)}|WTxz6*!rY3V3~&9 zp0v!8B`-GYzNBW$K$)i**YZKKl-U+BF!_4RAo*D%g}FtHOTO7MSmxpRC9%Tft(IZ3 zBgh`K441DMR+0Rueozc zPkzfXP9ADzOYsocc=^f-Vr}B_O0##8m35N5e6?m@f=!jB z9Lh%FE?U~NKsK@EMv+pywO65BZ`f?GBDt6SZ9(iY)?(T7Y6=B&x0D!biF6p&3#?4O z#%x{G&=iN9AwM-NJLM#Hf4?zoMoM36xlH&ug|aSce##)QRKr~GS0P6kwgUbtWR79i zK{r#*GVFHfX3EPAyC1q)(qq_T(9Mz^hCK^irOa8w@$ucPlq*@cQ9Mu_*}GEaX`T4G zXS19w9n7egnr59Nzcjj(UhCBynbF3fhzzhQ*>sI&L%^!#t<2iQ@Ln^lb7j=Eq-zu7 znLWZx-`lxz4Kv;M%$1Kbqxdd|zj15HpY9ds%1XniH@!?=Z5Z{Ym&?QJv?cX!^WJ{h9`XGB1>`l$MzrI3R*9YSJE%x09G1KX+kx9&SI&0(zX54#QYh-)S z-(Kv{9|*GF3cIYnfx_h8+v<>mZzR@+zWi#dOYUX%437_u@)g4!19 zUc)FyO|s`NwT^PMOg07Ct6*DGytdOrl#gf}*b{j>KY)|K+5EyT8nsy@$HTV(B4 z&6f5#4)&2@Eqz|Gu9lzOt#xbqylMTpjNL&@=ek1_g2|c>!NP%&zT z1Ge3;+fp5Jt^BoN9jPb9T6xH@$Dq4TzHHbt&|N3rH0-YkbDjLcun!RCI(gQx?@|Xw zTrX4FDYxsQqSGz}%g~Hdwq6c4x)0N)MXZ;T4f{N823V0{|4wtr8{`#+MfN=@ZjcVc zQu;dNjdHbN>CoLM*BUkmx|`%S!$v@NlkCupW8Wb6Fxw)w^}RG=gZ##@CAPYVjk0#9 zz~2_Jqpv4ovwX#{hrqVV(tEXTZ{JlBcgb32>!SY9_nL@pa)n{X`(6*$su{<(U9Jza z+%9*7S#FmPg<0M$_cGgvkC<oUgKo|Q$0-3r}v(rwsQuw$~_u)D#Ym#-Lh zKiCU0?hzfz!(hi{o?!>T{v`c|9Rhn%K4jR_V1Jfx8g>HgC7JlB4&`;Q6SBy#&WtIx zlX9hDA3*ntyw$Kz!Tuum81{8Wq3y5oBf~8HX4+npC3`7M-S?c5mCUw?lzww_MdEjNEM4qtJaWcN_LNbf3!u%+^I6>F1DN$QO+6c)ye43;BxHaohY-j(tq0 zb7lWE@=IB0*mYoE$tuG(^*<^8CF=}p2m4z34BH3GZ{)Rx{T{k+`BKd=6g#asNT*{mIOF8Kd?xTPL2+JcaMPJZE&L zSofvYMSYsN43@Ef)Ok3I_+nH~!=kfR$yjxvVd+_Gz{Y9D>5NmkM)&h9hm2EIhONsw zDdN-u!*0o{mpzovusgEcU{@Qq6S{b{$*^6}#jEX_aSREngIQaYZQv@Ipq>con!#Sv zOr#8a$CjvCpWr-z{nM7L>JMu+W#E^#Ug`tGrVacz{zt^hBUbR4-K4qdJsTwyBXL)KF%+ z-@Ql`F~hhrusHG}wa2jg2F{2asXj7nFLa|++|v}w7V$WAqt!TOXk!B%a*Ue6tS#z= zfhWZnRjqX>vy&oQ)f?UCupFy?Vb~9_9IMs`Ew_nr>Rrw7#if&AC9up6t za*8_6Y@=u%gl7}#f@4~D-5_sdp89~P^Ewhpt3@Vc3t*m8i3Z#SN~Pr7GnGieX(;+F&w! zv4&kdcpX@-VWopt$?2-fuqy|z0b5|07rGhBXV~@7%}`fs#`U^ftu?xiA**D$+Gf}z zL)L(G7)JYU73%kf(Y{-SI%?SCL$DfDZy5IU5Ud8(yN1#J*(~*M!)X6(ma-n#`J+9# zN|kOH?a5WD!G_WP;A}P7FxnrSt%@|`RL@c6%(jT+p?5^iQ4Yg~4!t+BTG{@@F|g%a z6(3}eMb1^3%$^Z*haQf+R23QK9eOPCakS(O zcBQ(_ubgr!?E0er?qCYQ*cB zt-GKx>PGdhVRv6}ZPd-G{0*%;aKSxMx2l&$64Pnfs9w`dM2>$#Y*e`mNq1VFosyb( zo7!wx-qfkFx2ZjbJvISP0MzI@wv1ji)d5zbnLIRgo48HQH0*t5)y8t*CCeB7!xCjOl_B59M_+!V0f8^2lY(JX3Y;Udcxb=0tFh2JG_QExJP zM$FE3$Sta98Torg?4Dcz-K~brELSO{mFnl% zqox-vvfQOc8@90MyX3o6DKj14U23mk6yIIytYH-2Hnn+0AP?K{CEo3tiEoPDPT8j3 zTpiMFSMO>jZYh2{WxG1w8q(dZUeQccO?#*J-Rc{|7J}WQI@Xel6;J5;A;eE)W+uZ@oG-wuUggF~VFw?ma`7ESkWhpJ(w@81s9%B)S)m24C3s`V!A zk7`f5dd)D3yPyYU52Z8HcB<5^tP{y)Gt=%>xrPk|!|T`ELjF2blxAWlbRBAhVUK~` zuPP0D0qgnu)(b_o({Puz!H@JyN2Cv#&gq&|Icw=`T6pt z)9-`562D+yA-6@W{}17W$9OB-+|Kw2P~p55m0`$j5swEYS{}eZhsitH@B1t{6XyOh z=(dP&;I@h%ff4kHQk=$$14&^j8xW2X zn}HUw1BiEYff3>WP>PTiXA~h(;z^c2&+ZdIi#YWkB)ZL#rA3gXRlLQP=a)x__n@_j z4}a3;Q?}79^go3YvWYagAbTag;E+ihaDT%Rc_B$|L_c5=cpDSBCO6(tU^n$kQuJb* zaCa(e&wszVmbUJrv}Gpy3ZXJRn67ohI2LW+wH^lQrMD#3gZhlkNze#IuN1L9LdAYs1}L zEw2mn6>>{)3x~XoL%yGFw1nLHPuobbCZAHMF?8PpHd>-{@ivF~cMkId4)bf4eAmtW zJ0H1#h$Z9Lo<4;p1xXa2I}EssAhC$c zfL5GzC7UH|(_J2(JMC^nEEqM|S64U1vYO?ga_Cy;wR}xJrB=tgmhHnaR5L^UEu~P` z{O~#%vJ4+J&es-h;#k7%Nn#Zp$V-IS6{aP*1?R3wyBF>VaWJS2q@jCCbiSTsOF|`% zv->r^BOkE)D=xS1jhk%LMU=0vM!+RvFQSn`Yk#`*{(EgP*PL$L#(WyTkE&mgxLOV1;cFvA{r|&|Q)crtKYcYy1B{5UnPd!a(=~ z5U(*M6V7!Xa0aU^Tv_U>2P$zAXc2D!(T}nGbH<+zUu(Z+%kLR2qbRhPQPg(+ zx0w&soX^p&rAT3489?-(>>duZ2%Y8*ZlPnl$@MIeEEQW?#Kmx1MFCKX3dZmrCNz)z zzmC7UpP_mis1@Pv?qzi)r(r4M)r{9M{*rM=5S4f+=*D|J+)F&l5*@Ry!Uw#0ihWUt*$zEi!~FZG#tXX^hX$qb88T|(i+@*HMa+s?oMJG8%XipG_i6W6WY44tywTBCuKJ1GkAX#@WD=!mdVUKN{s?w@Vde zKOPm$`>M;-{Ol}zbAM^}v8aQ>m%U6L6xT3r0Fvd4cxhpCb{{!W?9YBDs!jbNd%d!& z6&Vu{=F{09N7>bh?9ZcG6z$U5)f@0-SMOzi1NnQ|S#W=x{heH6XqIan)#!iUdhjdPfKBC&jZo@v?4P%R=k8#S6sjXwH zqsNGQ#?Fr(E;`0GM4y1%8+}UMGxnr7rJjcUG4+f1_0gx*>th}AL-ut>{RsClq-|&P zw<>Ym9>#sq(n6(lgBmr?&G=OG4T|0)B77=(qnbT#zM$~`2jO2e4tGk8iugF1@?}B3 z>c`POJG~V&M(B{2k5e&Y#F}xDz-z}*N^TgJ7DH(m6LUuWa-2h+Q6xXD=*g^I9f~ZA zIj!!1e4~0`Tq)vxVBA7T9v-(!?nF+vaqRUmr`XqU@%Xq^F%!knajh|@#R;V6w0J*) z@HEHu_i@$H(SmX`&)kaz)+g{bF-bBYzbhuoGI)G@j9pzY{!zX=kHxrD_V`0F!?_&B z0P%#F-(!s9_ZZ{&J;rF^9skdmdBQpHvzT3C)%dStX3J|>vT6J(IZxcr?w7`&h0WXJ zt+DgOC*$LQYJvmxCvie@Y`%r^J6lYikP|!G(l%jg>^#fn>}3|a<*o_;jImoDWXq!L zBFJf1nQBO`ba8r?aoUzyKAEs6w#Cx-Vm$rgJhnmJ5PO5A@Lgu7vB}T&+`4n_r@NCoS8tD>j5oFh<~$pF!ZI?4BvXK=MR88Er26)! z*bfor8?k3Bt8@0@?q8d8I`$yi$a?jy<-VNj#R<#9Iq%21#4#Jy|ART>QHDoyCZqiS zoP&ER{*to>p>^iG2>b`IP2HEXUP&vpi__x!oU3f#s-%e@A(pg>XJW^Qu@nCVch1Bg zVo!^LiPpH&f@*J)b?(F%xUZPFN`7de+OpBIY~rP|MYT=5FfPs7HgRGc)tnOGZ4)m8 zjuB3Z$fr!60Hp9|LxP%bwNIYb!w&b19m)Kx>vml;o_~Vcqv;8qX%hF>?XZ#4!bIKp%$Fa=`Ys$b2)wgO$WMaZ>Ib=$o zgmLh-)Dp+qQ`WpG6$!cg#=vRoG28rv)7DkMTzRMZ`*_|2{M98?_2BsDa$MpZ{}@>gxYBwpL)%*{BFu`60$6ZryNhf z_eUnYoluPtVUeX;P-|TPNmgPK+dEi3&vF`1e6l#qBxRyZOyw zH&WOP3B5V&7WACS&F>H6|DNOR;^FLfm-sllF>#k@o9IoX`g4amhWfuLk!qSl?&A>l zLED~qP-NykW;+P?-o!ENcT9vouUU?XSeG|7a!kZ+c_&cWw&yLAWtJtjx8OczdpB{m ze0<8G4e!q_teCYgxVl?)gcx z#ejTA(q@)#W?!4xeltJo+z$C&F&o6V{MAXb<&m80lXl8uwv9>Os)_lV)NBi-XEsu6 zjZ4CNU#F8g#N7NvmJYEvf0f+BeyPXKN6;D)~d} zx`KN21DgvlPFWr(*cbhwbq^#TT7S=Y9C*g^R>5DA-{lm(i&QPOe5+0u98otQ7kIY} zSeWt=zv=xEzv)fm%fghi;*W)^fx9PPmtvLVwn}oJ6*CL(g_|%AGn~Egagv?`9~93Q zK8UwB=qd0)@mIKeLVH(ChNKc3Ea|=R!IIt^&$8?)>O>2A6gYxIDCe@ufEzOhj0M|! z?y{UHda!4fy$^Ej&6SO|h0s#}Ks5w20r6t7HSUD?E8{1{^}UZl-U!T? zhTadgcZT&_HDcPT-dUE((^`A`k%D;PmtCme`gD=$K=o8|a zY4yEnmhwjIsfgcA%fdTfZz0SRV*ivGR=fIeT6v%0;`3>kYl*Wgk1UyC-5}{Z6dNRc zlVSsxWSpS)dnbyEOFVr}qYr5YQtz}`(l-J&OZr~GW>_}M&9dT>O6z7mn{Ybf&XRlj zoZ;RBa=g{QS<)N+nmzN)Y#;U6j(c~t^^|zG1hYi(G2=HStK=zREu}GiTi+Mqrc+y| zL_+BgeNKz)Vb;_*L2m$@uuwRs1kEBkI4>QXmk!QL2l8UKc5q&#Z9?g7whl?(9l&X1 zd~u*d($@z%I4>QXmk!R$K~YfZOOQA*YE3;Ork8HQI8p`tR@qCNQs-fuYEGrLvkFKv zYL}`nZG(HCZCxsjK6e1umVSn@X-g@MIJ-)Bq|&(4kxC=-@zig{!O{~5`ALMCWWy*1 z?MtPdsRzaXlR7o zLtN*Na$PzkCzaisa)|5gQLg_k_2-=A*yG$fUSVHvGQP_;$Kj?BG*Synv+bE)**D9w zz&fw*Jn`7{C4JLuFHc_ve0TcK`%bip8TY|GV8$-skQw_SnKVZQomdX{Bs`A6xyc(zGx`3cNYipn=BJ4}kx;-jm zqMTd4Mo#2>O_X)zC-KcGcX=};&5*lL<}bp1pu8xf1@3L44R}((T`@Z&PEk4B$u=#v zl@+zHX{#XZ%@tSKT5LPn{VR6=zG97RvAtTc7&hNkG-m8Vogqs(vk{VL;6z#6&!0gn zwMR2(CidHmeG$}8?&CJq6YU!Ff7Nr!Qp;d=??b$}v#3RJ{gSK|c+x+Z(=%96A2>o$ zADCpVnz>4jP}J}BWbHT(;X`Z9OpFn>pU<4%@1X6LnLDHBVRca7k7g{5{mNwf%(cLj zf%6l}pRwi7dJtGOi{^Ec${y}d>(KY%c0!WN zIh`k#&-!!!+47gO{@Onmx!4<@#i7lUv>wS-J7T=E0Pe*tAAt+`~RtZbG=TpGhgkIIjuWMtpUH24}(*%>J#^D588%E&7#`wxhY zY=N8lRc|z{0@f>+yt8tROp82PId_1JJWzhcfLwWJ$-)8UDEZ|Bs=4H=xy)%jawD{D z6OIm80QqaMe>mse0WOR(FUkdMLp3%wlSY}8%zfx-`(~C!j-Nd?b9N-%-+7U}$4-P~ z(d^<(2g1)vbaVKAqdKj8rTI>3?xiq3f) zP;|cI5KE4-_NZ~w*^Z-%&U74SIfc-eb)0Ks6ux)SM@5NJ)a)pXy;;CYF%)T|h_!pf%h2u>uK~*?SyoC4p;}T1mrDv^fh3z+Nj44{9}y+$WeU(OQ-Mvg zAFxAG><__jvUr-q`4doyzsQcLD4g2r1NrxmBqMH;4^a<5UIaJNtjO+aKcKK ze_>3EU|+x}Q5^9yoOzpp8yG~7&i$wY_^GJ;C(2)k@yY@X(x-vfQ9U9hIl%w z4&Ri0GiIl_*3w5EVLZ+F4*Qalm@ zpYb%~JBoZs3&|}Oa%ZtSpV7|vj)nY6E2n`mpRv$Nayz@*tSNA}vHJ#g-^bdg7%dTG zc_e~DIL#<+9HWioS?nHUo6$3;e?GhIjBSiN8ILdyiX{6w#%m)fg!>rZVYEb%WDsK^ zW1Yb_Vy!9HvirWMH)4DBypP>aF}}lSiDtiyg^YEK*D~&8Jk2O$IOU91eCZkKXLnu< zrLB92c0a}LPIkY;ZV^l2;5!b;OD4Mqu{)35wT!Kd?TkBF zdxY^cql_cJS&aFNcE&cwos35qPc!EAAp2UzR>pS5!;D85I~h+iig>b@jG2sCjCqXt zjJ1rdjBSkVj5`?*Gag~=WIW9%5;$bWOvWt6JjPnaR>rjnRPycYKFoN8v6JyMqfF#- zV9aMcttCk$&u6qVwlVHxJi>UIF)x`cYZ>i~t&DAq?TkAa4>KNN>|{L6C{j2_jG2si zjJ1rdjO~n~Cs}4P<}=zg_I@XJdP*DP5ysPuwSB0bv@*6c9%k%h6se@mWXxl%Wo%_^ zXFSZ<$tcp;o-vQHma&zwo$)YZC!^@g_KbOqwT!Kd?Tm*RI~hef+ow|=^B8LxTN&FK z4>NW$iVQA|{%p@!%h=kV!f9tb%-G3tF@WtE^B8LxTN&FK4>NW$icGSvWh@#4>NW$iqY(gF^{p9v6Zo%@i1d2W8N6D zug#_$wKBFd9%k%h6l1x381oow8Cw|-k0Wg-qZrSYjCqW;jIE6AjE5OJ8N~#)XUw~p z+_j9YjO~n_j3S4$)*Q-pCcE<(i&#?2?pDV3NtC0*jGc^PGD)nH+3#cuCy%j+C9Ujk zXY63fQAX<&F5xL;f0*$oOFG#trjk69F^{p9v6Zo%@i1d2qqv0QWvpdvWo&0W%-G2& z@;GG1JjPnaR>pS5jzUV?QO3L?vae-qEux&ZGahE_WE90D&t%MFY%iV>jeIeRY2?mi ztYvIv6eT3DWo%_^XB4F@XKZC`*I343GK%ROCS%cbYW213Ze={o*vXhVgDmqHTN&FK zab5wB%%|ds=he8*7Du99jruT3L?=Y|icX6j5 z-;Mq%`upgFn1L}lF$FP|G4o=YVy=sMD(1bI)YzG^t70FGJrbJ`mmQZER~ff3t|@L+ z+%<96$K4cnOWd#H-iZ4$&e!9f9)02~<6Giyjo%*sbo^i9KZ^e%en7&)gvANBChSc3 zB4KLcti-vAS0vUXu1dTnaed;=iFYMFl=yh!vBbY7T9dXUy`1!V(g#T&Cw-ChL(B*NS|2Fwg$*(7Wko6-|MDcPxX4a*WY@5((8v_ zvwP3)eV})IpE-T%`rO>7qtCDV{ISpLeLn9KliDkFLTX9srKz>4zf3)l`p?vVr>3Tj zN-IvYr>#wUG3~Eu-=#(M?caA;-_d=?_s#1&qwkGATX8 zrT;Dc-{~?VDx*)vgp3&(t21_FbY$$x_+!S2jDKVd>Q~yYvR`e#=6*NzyQkk{{hsUh ze!pJ*GyB){Z|v{ye{=sW{rC4j*#F7?Z}lHMVCsNb18yJij{#=~WMz)XbY!l|JeC=m zH9Tu(R&$mG_bWnJL=>L(M~iq7E7I_d$1M8dGQQF{1ph_nLVS^N1f&;u9@ zF6M|#?E7blDLAe^6&8ii(sSw=VidmPH%83DbLmQ0&c^o*FT<1UD`8QCuLjy-Rfi|m zPSlW-w$s4ZZSMi+M`qyBc}(;bz<95YYcMiL+V$A7*WsoSr z|2!0;n%#EBh90qytYP;pj5~WIK=LTdf6wk`+3iXo`LYBGr-ktv#)x$QK>RQh}~%v{$pt*Kg#$LOa3Qq3bdJ#vw^qtCGA#55BvSP??%Wq&g{Pf>$%JO zQ#iH#JK%OOy84r^oJ^7zFji!eUltn4@WRd0PS!DBd7M09d#`Ob9{?R~^ zKQoAM_7K7v#`+;-*~@ZUBuaP)Szg0v8Om-h&*-6Kugg}Kw!RmOFCqE;=xb3=3aPYX zNB)?M|6wwm-1~=s41&Cgk-i@) zg^!WGsITy4^Sp%FX?a)qQ%$0SJOlF)S zosdrj;?By&aOX1?N*5#rj74%OEj8LT&*nd?(=`+z~(}MyuZg$ErU7 zC#olaldw;OeJb@7us}TxtW?hetJE>zJoN%_f%+5b`+VyRoUB@4tpHwSO~C1@TI(#h z7g}cn9aa}?7Fi>4!m1teGO-<&W#S%KmWjLIw@lm%%QDdc%QEo*ET@Y-kWUwnz;e3S z3(M(ZKm1M?2Vgl}JO<0@;&E8Uh~GqQirE#f5~35T5^56OO!z1v7XMpvLgLt@$w||b z<|Hji@+N(g)H``Za!K;Cnt^c3@v8vN1kS>>5?`90jWFh5bg05eKwprai{GUP|1$h8$8R2f^k)%w za#=)}t4-X-ysx=t8u>`WN1N*!b8R*HYs_`6xvmqcknZR@kyJ?W+$b`Oh~FsikL>Yx zoAJNdT=y7%kC^LTbKTF^MD($g&P4RD`Z~j0E6jD4xmNKNGZy*hM2csl;hW6$c5~e( z`z4Y7ZgbsXpW`9^%KdLupwzkIbnrVzhhu)AOK6RKZwzWOYs5WfMI{n)+UA9IoAP|q=z z4|^7>f8lzl*8t0BDPt_Ty;oZ{_C6&x_P!3+U#P^?LPdN*+I5x%X@zQK+9`1izm;kE zYC&2oe)*7HXrxQpG+24|zc3*o>VK13nN zgwtQ#Sm$kN@|#Q|!O(`%R_O68bvb<@!KF^GYf(!f@}YfPYInOFC_7K%xqMa=Nrk?Y z`JD}v&oCP1G$mkf@QHK6;}mm(&ryVe)n!`N=<-+9d0kC>2i&4;cC*vlVqfUirAk5g z#4NAF=`CpCgv_xwIy?h1neQ5U&Tr#y{zZ%Z(K9~HK}ngY~*f;4C%D(o(I zRfE4tRN~I+|KkX!7unKjtaN%8dAtqw#yV#;s*gB_7uMUoCiQcii`=N7!BQ=5Y}QE) zOQX|QXDT06c|_!|ud*+9a^{L!8to0H1_?t#nG%;d7n&+*@=xKT33M&3?m6^{249`W z>vk({%I~W0DpacqodI4 zL`^Pod69dMx21q`omwKUd=GGFmZm(L#zGa%qngR-H? z-x5-y$@}dt)Rl8mVmN!!c^_HrTpTwXIc7CE8$-bmV_T#vD4pi@G>|Zm%5qnu zv(VFwM#>pP&2p{coRAT@3tDCrgzE}gDuR5by}{`tWgvJoQ*oKszQz8NhB=<~Ds5QVO zL<-$byEha!Q!bw(r`zdwhB-qS^|(F}DQrj>drA(BDLNo=R@9(_d3(-1!cN2-Juf z&K3$k;H}W(Hciwwk_Qmfx3W+>LhlUYe7Bpt&2cuM@XZA>F|E0=t~Q&aqMlI%;$vc( zNwtRur$Btv8bf_h$Q3kO<_Oohk z07ae#w0x#vPSUW9I(2qXg$PuX%K8?ctIqD`CT;qK@S0K8cB#wjZ^q~zZb!)vOS(xmCz+EQNNSg4o+rM!VQ~fG zp<=1xD(qQd?vSs$DBOy>uW%a{7z=8*m!YTj3S$ux7z^~+T?~Rep!fJ(G$eL4>LN6j zRSkBxyR2dHWiAKC0~23Y;W?J2PS@gk|GB0{YHZ704K9C|Aj2faroz6mi$#zdJ!-g~ zDw;$EdBDG`v8(?8r+ZrI!Il;=w5e1m<5*S>0H5bJ>YRERn~j_9vaIrQPu5+os|>>kNYEwbciDuC|W3R+lL<@A^N<~HK~(=rmh8|KKO za8^Y{epO)EOlxDREaXenU~cZG6;#Mo?x|Z!QI!QWrjJ5OM$%H7`X^p;)9k9!>+)cd z+@d8#PMRe<8|%P%<-wD@W|u>tE2{RC1YIQSfGpPtSL;3|cAXVF80% z)QEOLHX9y(=wz8%W_mHdn5i`$sCWzAI=d&7}Z&zXw6oQPuC&7 z%^|6&SP)>mo{4#9LCZ`mwF~QAZbw*Xw9$a=o{)rZWwm{Au>T6UL;C<`1rl7d>pL1o z7t`Iwtl!HkEb0V9jC8Zyj%lc5L2WoEJ(Y2}bGb8U&_zHNLGQUHdEM@GZYVw7b;0Cx zSB0geyD~f--L!#%3Pmh}@rbZsMR+J!(wTxVy$@}dMdPV%l{**Pc?}wHmt7j_Io;HA(#%qC^RY9qJ`{R`Odxf}MP0D7aj_Zcz(RY0 zJV~Vb(On7&Rx#zC6;5xt(@*n%Et!iAiZIDEv@9NXu{gp65H=*~LZ)F$%Z(y*`e`n> z*o&PLN0@;ZyALj(v(n=tf3&LtOP%z58iRg_0Ud9fcB}j#ha#sU?^boYSx}}qf4G{wA$YT6tJmb*-{{dVw5clcdH0dxFK{(F^v)`p z0oLxc3JHb51xIU58aaKa0Ri`7stvp$s|OM7BqvX77z#}f zVf54>kWo|Hs2ge21!&i9E*MvnHpG=UZL+a|9k~>4xAdXbaRA*F)vl)QLJFyy)C3{m zgPI$)dR=j-XP`7xd%_wP-)7WEE#mZ1MK&}yZfUb4d;BP*TX*iz?r;2K&9r@L79*H7fe!V_=4K>G-bX}UxT=c z>ZmI!^HH}08#^BL;acr&rr@Vxw#~W6G@nNYvsx*(`&#&s6xTV-a#8()4m&V)!`Fqe&ZVPZ zjd8QQPB*<8T$wKn2*^Pa%rj`&K^~1WHyBa3s-IhtGSFMkPc zEmUN$t1CJNvNKf_HEp@mOAjhhVeDK+s5B-vDy9&l^1})y5V=+cDQQEAA!Ue>u4~#z z-&LYR=j7^;*-6r{q?0C$(jrbLwOjc@6-ZilT`*#>w{n8_46%How+ z73imx?7akD=&5gLEm+v>rFC4T*HedG(%??ioaROyHkEsj=sU%Or-@15uy9Fkz`9#; z;Kqa*c2fuZp(Mi0xLyWlIPBn>L5pgx6XYOCVdY#F&^4Frxl`A=4k8y8{$@j4twhK4-&1EFa2oT7!Cg>iKC(P|y-oq0q4=@wWuFunngN ztLDb(age;ybT=3~cyO_(`{!^8nR5nk)!M}{;bjx|jLrr6I!$LD}47jWG z=oQ+1g8S?c}0p~f`Nskk_ z79#O;oNk=-SRQOR@&JEKfJ~XHILm&uD(DgD%?^y(l zf-_R|w5~;XcJ9ZPjoXDC_@CN18+rNo(Gv?pUVP#lf#&s?st3ZMNo`;gPE`5aIu@=t z*qX(O48JohK=iZx03t9}XH$j1G_4rBaKSZCm*X8~(LS^UsA8@}o%PZWwFK6t>Daw>^>Fes*yXFj)^uGx z?+A;9&5IVHqWLk&6rp)L@8Abp3lhYO9uACBSJWkVk_2s$D0;qtOSnjnN_CjJ_)s}G zoMtbc2w)T1-jMJ0+FOF-p`gvo<+PzPV3$`E*R!8W6RXo`=-Y z*-Re699SnTqlXG!%#a288v8;!7DV)PrfG$P8c!qJ`Kj0PHPOn^p&x7Lg!-D?x=IQU zA4>G0XtCoa?B2ybfeD$}*0l4PDP!qtX;_FOESz$z>9F$CN2;)cOLD$JVGrbKl$oYC zc09q82jnulZguo@hZ;V&$GZBZd^HdI8;y~xVKLPfKh*#nUK5RM)P!|3OB>S)!+l zbVI~!6qFCcxxfRq2Fw`kSh^w~xL(DN>Ty^B|{PT{2Is=A<-(6gro zq|`02$nlGXdBSgg+biwE-)y;4>S?7~#mqokOi(jz>(W22MzT*`fjSa?xO4S&fHY zJV~mjXEE6Gpd+wcHBj=r=Li{Ju{lrkZ0z+H(5xOk6)HkNRNP2AIKoADUrgfGKrIXd}8Dyr!e1O?9)O3|DZw7;fr#13jhSK?O~PV{XEo zrAeoY_F!FsEls|6fv2(O6f-}<@-ziY8N)@Wgco($t#o04H#?h6VOx@}E*o=x>~A4k z-03W$eXS-lU*-Zv-msqM>WL>D82nheh>mNp3p+2tv$v*kVi#Wcx^DlVwwlI>TS|A7 z8aVee+`t_J_ejF)Sz#>DVbIVR z+$u5aeysQx)(P~d*dD3JF1Mf&w~>0{CiFxrXzyqdJ)ZU{I!p!xY6hwaHv+Cn`g9P62b!aplBjn1-Of)JDfnvqzXs!!uW&s7A!S&J+v+jXadoj;zuzQzwR~4c~ zHG9JnkDl{Vm(PXlg^cNtLWl(-#H5S1lDaGCPIObA({mU-Z{T8##3B>Jx)Ti`ERDuX zk;}fg5%-E7cNIAoHZNXGg&&Gm%McQce>hdmT|Z9%Xf?T#UA~aH86wCGDm;?GL?EOs zrWYj6$(DC9wtUgaqXE!~VExhoZK{~lr^7eWA(vZeHMTebc}$mX77e4%hc;Sy>tDX1J-H@7FGI`dbyomAi)H0 z)*?~WywEgs3dVGRsDqds3%%Q1q8Iv`_n^Qw7!if%J9y# zMUP!W4<+ z?$o*(oHxT9*51O~rDKH;Gvj)^1!WGnPhD73gNYHnj1YK@11EmyV3G^ZKd`-MYC8_X z^GSH!2%X-*!=bS5qexGi^~yNZ@Q`xu^l?^{&qPt`1G{CcAVHaak;+xa5_mDk;)x<$ znz*1x5~hihv=oy_^wcJFI;vwNo~D{&I@3eTfKWjBrmgGq&{Ri!JhrK36d1XLJ@KBM1y6bDOTKX#c67U#^ zn^HOw^X+E0-5Xj3`p{F-L$DH@^T7F(E^)BTr&T!3)^hAN&G_5v! zw|IYmPM+}o6B>uV85zLJjJgimJHcUla#mpgaSCh=;T%I$RO=Y4qS z$&UcdeZyj!!bKws-Z*THV5N_C5l$$rvGpst3hO zvC5-?#fMIoPYQ92vuOs5tWbHI6kwl-XAG5eFGyxe!VH-t;n#b}VNU0f)11)LQnwrD zE9&UP930ICTcRqV&$yexmh^M%f%hWFL~nitW<}x;O!^vDCbl<`nLq%{e z2sMQ&XXA3uQY?C~E<|DK6LfmhfwvU&&Wk?utQ!uUE~I_jz%Cs1VpuEUeGpF-Qh-p= z7rXRco%Tmt(fUm`K0mUM)}46bMl&!>4g-7aVFM$V6K`HnbD_ymmj6lU70$bCY0w%s+rM+2X<~| z|I3U9%=G#YCyZSVoWl>zIKz@?1}Ku~xrif}PfYf!nwy%ihvW>K@T2F~Ro~=*UIYlv z%drg5Qy!A)6M}e5fbj<}>2c2^rrVd>wIU!l(*-;aqr>@Tut7IxywOt?9e{cC%^NjE z1+*qbW!K#WJ$I(r7dOl{V zk%C5cJ63sKE(UDhl8`cjoyXd-=#jJp#nz-fjK_KWIzvCNb|R*Zi10!?SbhJ z&FIV}5LAG&UrnaD?RY{^&3hm;Yr{g_?=^dGR3EEp_YTW{nz&%g&+EtC2z36_+#Ynp zK`WY<=z)+u>Dft`AkYuzFQmXI9O{vgy+t)O!6K%yY&4Dq=c4U<{Zp6J)Kuf{iCiac zPLODws|L?n>0LQW0gJR*7diaVNRGQ)&$D1{7ig1a(HUx#0Yw3}Qh6ufCsbA3I|Wv8 zH2uMhnm%_y=?PRZ6lpo8+|_tjnTodr^$`;hrrnwYDiqBukYswfLf6Iar89;~2YZ^K z;#f{ogAgTMmok7r8(0EpvZCo?vK|JxlOXtG#`?mjgzUwe7yr_yA z*Z}J`DUi154+QOQfH;WT`j55=iUks&+iihuwu^4#e!lmohT1py7}A?vHct zJ@?#m&OP_sJ9lO-&+Zs=R6&$6l2)-6mpG-Ln@Gsn8r@-JoV8Wsa7ux2HMUGC$>%=o zdFRV)@}I@nOO`E0f_8Am?ImCq>NXk-t$lbXwBWX@jMOP3k{p~leb|03S)`me^2ok@ zNUJ-M%f~pB$g8bwdwq)&J=uLn5H3~;EczmnWoVlHA#vP?+q`qn90$fbuPQcKQu$R)ZO>?%)- zo7Rux&s?@Gs55qwcc9i*MS^yNF!{1Coe^Vo0Uh0LYoD;W_JbK#Ypa%rwKc5(#`vjO z8{;Md<`0Jt0ZazF3U!9On-heVJWfpu-f}Ffve_o<9%g!IjUUnHYM0ntwavXEuf;(; zh%)V)t2O0K&7Jz3n;V|E$VQ~~5F|@oE3BHGoQaai+GDMs(@+}Pa#b4N7@9boS4qGN ztA%1z46(xXIEtoOm3A-NVAgY@1%kEgcWcXs(MdjMlE~ER#2sc0Nc7xl$en8?CYDIU zJQ^KY3ku<0UEfKk+?qwl@Sn0eUITPytwatU=#092uFbRSOvP>`y;hp$+0gXDSOmiRMa>^e`t}TE!IFv4)fFOOLH=K#9EDr z(_z-hlJK{iq_y8}Scr;$bY?y|eD4^Iv{aMYD`HaZ^Vs}_lT8ac*|%!A^b=!0NjCeO zAT=<#@sfRX+t`XV`?ejktl8Ubg#(wYnW5Cwnn;s4AUZm!%kc~YK6WhQ+3_BZOFEp`SARfyV`2*xXTF};5Gf8t;Bm3bije1&ASBud& zyWMm1I(ES4yi!}c5k#ER)NSShY^US;>ApW!7^`{fRA>g9n%Zfb225iC)P%S^?6kXP zP_8FyI9svS)DB((c4(cV)l_I{fhnvBp*3uMLCj}1?O|<+i>L~;P5iEgJr!Q+P2QV$W=AqXo16mhX6(N3MNMa|57 zT*X@IDXcTwZ9A72@Cr4r)Jm7BFljTj5jv{FKaE)PDlWHtVbZ(Udc{rBiI%BVXf<4O za?BIV97y38aj z)NhcN*q^p{)aUq0jXjAQ-SJUV+}#=VR;^%}YzTwC#NVEorzK^dVvE8%(!m zZgiRv(@%?A>!~{fZYn!_Y4xecR=9Ni?gaZ|6j&vF+fW-9IT|Df0JF}+SKP?A#zxK3 zYN@@Ka=YE}NtHlon-T1eW(2cgr4e#cW!q0=st)G<)rm~#D~rF-Y?_s~d^9S}Ju|M+ zmb6*jKl#XSa5jwdW!%-e$Zg;=<`TEVK1O_jTeC0mo*{&7XWwVZI}Nx#z}t4t{$BeoXM5$qaKb>DU?KeGz~nrwUj(}sjM;pneAGR6lnd+A#%#F})Dm~(3UZc_J;ih0czvS55-r`s z{kKzQ(mVx@4;nLmg#L3(i`;Y2<`L@VxFIo7$6<9jp(kg1Xjd4UEf=Bn$prrj{S)Dd=$s|zOasDfKV{iS1JxY93Z)k8z+p+6Y07Uh0}SaFt~TDpjs5#zyajui zvMC&Cfi%IK%`t`6@+NqU3+She$vw_{f{T?+?jYADA5mK75?JknfrrdtuvL3p2%n*q z+a|zBtay;65{q%1VNRzn_4wJ%}q6D{=XEh2YI%}!S zC&an5TT0aQq$x=p1$dC(r)*1)gUu1}c!XMA$^`X2Zp>g>^9l1TkiTJZdIqS&jPG9l z(=@a0FmYY)J;nP35RdYE82o5^`!HV|agmWY!6} zYx(Y@vfs8ph!>;>D**(tq8-Mhpc8>f0I}O_k%00tbO-iL1OePEi%cI4{hduyyLMYm`yldWCI+~c zem8AR)3&47Rl>W`!_QG}h_4sf3TF*=@{o&02ORxQx*9IDJj=8CVmetBm6`)N!~Eu7zP=YmKAUERbZ} zP3uq~r`}FWTC&rM_dN$s?54L4;vS_9I_d}`SKgJ`NV%cp|2ZpX-e;!4(v6qoZkl?U zFnrlnS#51Z&JUnDrqCghyap~^&y#x@%;3o_N37Gj_^ z!>H@GFkoj-^$410`9f-**N7R~OZy{gKhTH?*7UoUUH{#9hysqEH77f&GFNWiO<1-~ zYC=7b~n@Ik&Z>Rv*R^EAOE^cpv2Mm5S5)%#9<6+UCBb-T43?uJ%lv?(Zj49W9O zAU4yIexJAH9z)k%rsd1jbegYQP(4pl&O9hvMwXnLd4Dwf!Tdk|^7+@k`<2g}`PuBB ze|4+*i!YBHei@jP=n2gln*Gn1KYwA@tl+$!r^%BUEIVUng${ip(dQ;}H+?z}rOq{I zy(OXM9*s&u|9{((=1o3LeVUz}<>l~eU0fWrR>J}pZLfwKre&weHP^GW$P5|p3zNI) z=qao4WdKzy$}%rB@U1!RRf<5HU?fe|QZ1J#c@o5=qS_%Hl8%M;K&nMxnkL{tqrI&b zJwA>EK`z7WbNs93W_PuYnuD=sVeeP@Z8v;VEHrrODnYA}1K{m#G?eZl zzNHc0LhLRCb(2+J&X`}I%pittvn7f1KpUpRP;HJBeXp5@Q)?8ygS*Y}UmK@kdMA_a zlEuu`B8=2?4OL2uw1sv|v}jlh8u@r@6cAtf1`IMH$ z_m{_Zty(v&qNfb>)vbR#%w?P(2HO`IYqwh05^0YeM@_H)Cu6TQe`|fKFhzqae7GZtSwNw`*KB4l9=FkokVXyk+fxF7;PEVQpS21_bQNMgNTlp9E`h5_ssj0uIabAVH z+|=(KNT>dEBA0JxE2DqS_FGt~Rrv(c^r0k89t*zGG0AlXf;Xdfwpc9O3cqP0Xt^;; z-J0Q_!|Znat2sO6WLKBkboprs&D`pZHDU_qSarDtkbIBNQ>)g}7#;W=*m|k{^P8`r z1U$eRMaW#^y_JxhJ^FR4hx=@<}AMj&%GWOx`coJXnB);p^lW_o9IK-ktUhShSpP#`bJ%+DM7NGp)V~~7@wH9~b zkHl~A^3AbX8x#2qoYzFpo8fgMd`vm@S;}K6f92!+a-j&l#@pP#7QW(hNueabJn5DP zt&0O^@TV!wg+ZDk>0SwAr73dtHZ_8I#AyVTXqEbD*z)R%G^YttJs{{r3+!`sI8S2h za>AvwE+$+`x|BFg8*K}T<7?}a(_r)0YZF1;RF`a=WDMm!I|B6=;Jsl&PGICNxPZ@i z2Ojf(w14E8hn^|y52rqu_oA=8;QdZ}$`?+qNU2_zKS-M6JTl(g)RZ?!scyg2?bpix zBWOvv++b&j-~ZVc54m+=YpS${a~sZ_(RaYNmpO7`^6=Var03G@BM0FydjQX&wdN(Jqp1^o*+1>`$b$5$h@2iX<@(}rdUOOgK~HMogDwKUODJ>F!qrnQGqI~P>OHQO)h;1>Z^!lMEXl*lG+AdzM-CqJ0Ru z)*!KCo|Fl;oLMyl>znwkXm?O8H0!)Ey}d|~Y2B8d>`dMRGl_-3GH}%PqJx%xFIm=G zlm-l3{a$XrWxNIYC4um|B$3+FVMi@1cK3Q7X`?@r&l#^rqaly7CP(ewi8s719U^h_ zipdHqFZUERNrbdx=(9&XVn3s)%=P3cU;H_c~~ zj-CQX`Q+2%Gv@ZkD9Hs5%&6K8l?gCGtuivisq-=-ZgVgilM5C~`)AsfhmyDLrFWw3 zB58d3l7H=mYwzCl+(W7yg04+-Tz+!x1?a1smq?d0It?w^uyzhlwS-*i0?-RK)$PQp zly*$d*tBE^_BQPm$UUuHemCBYqdx38xxF^+7Tw4HH0IRX^SLv2@AD&Xh{&J!kIWl-NaIn!0v%jv0@ zx91$AHcu;Zy}P~Ad%#Vya}JpFWXk>U`$7XYwN|%_~+uv^cp3t9O{$vx3ffhE$E<1*+5u ztNn0R1zj>?Aw(1hu>)IKu_f%~F?3V~J>kyd%mSeuyCoehqmnjxEm}2LM=NF5`4&xPzSwk@FG~^URzq3T5uS8Nw*5%#@e zIZFm*0+Znx_mdNY`itzRSd&uAgK5@oUMqqVI>po3B!0IsC0Pb)2&YX zE{2Uzv8xiev|=&sc!hY-v&8;rk!UQvC~a&*Wz+vNUe#(yIt^WBE3uNtY=pqDUxtnq>r?EGeY1)H@tVvNE0Vv;5DA-=C$E<*Y!a)8SS? z37<_96v!o`UM%Jn3gdId_(dvNqytwZFF1WrZloVaCeNh6{6rbQc`v)ExRNXFA8m{7$DefvT?NvN-&k*WimEWjV>1RX;^xYM#)f@7i^b7 zAzqNaT7Y%@xcWx1Hy-MN8{_Jm{c-iHlDlGTWvu#^Wj>eosa~&x{MMwX`r9iYm0RrS zBqP&V&UC+Zw4b0WVn`@O>ZzE`5hoK@sI+r zx>t^?*W;nE(oqsRLL8)2Lh2;Uk9a680?}mmhzHjal-6R76j>#`aV|jKH<&ml#Qr!? z8$XP9!NvAX8?dudRCO;>XQSw96IH(tMjkH>&-b%1Q1$!J9NmGim7L;HXoD3dg&HDR zqFNewx3@%v1in$qK@rFhSKkvJ-%`!IkoQz(x+->sZ-I+n^xBh1XU zp7%gLUJue5!U7XSDXxAyu6`$~{!8&CBe2o&<-daBVbqrNHaWMz%%Jx@3nb8DRQ*YR zYog6ls%Y^OOV~lrc%G$DZM_|rj4EgFYU9OHDG0#R7e|}uxTsBPxzrUfyOUaGPJqO5 zZ6d=g*-^n15%OV}%+|$DiibttMoXnqHh=^^uzpvNEz|$FHtGAhpd$&1!E1-$bKfiV z`WnPyRFnSoO1U5l^f4sDHh3(6Bg@$^%+o?#n^hJ##{G8W*T?+@3$OIJHs{+ihjIbE zBI!^u3_9Z4Vi@|&7x~VBZq3?>5X;0X6kI|f8~Ej-kK|f=r1r&7#a|~WPyqsV^7n0B zbACzqQjfATLdow4WFRrq=0P?TvLJv_R+}WuNY{?hIkY}m7Oi9Dtlz0V$Nd)5MIfP| zt&{kM7tpB zj6`%a0E3~Z_H|9JXo4ZeplqL1_n80+jq@jH%_?XIY`&w4hQ1U8O!ba^zKcZzAPAM# z1$kGB!ru^hTzePl%!qsA+I#NxEtoh&KL#O5aqU|KYu}O5fh1J=J=?AKnI9?{XBTVlm9&rNug!PSVYJ3XBG$f_JpXnm5?@^}%vJu8#s8?-i!b-tnRmC*b~(!P>^1+JE~9SDt=VoOT+t6CEczgOyM2T6(KK*ba(g45(6Tx&qVd( zasANF;M39+7EhYL21&|bv5%U8w zt4bkWz6-r~4O&1GzdMkK%;p)x=qOrY7Ta7z>@$6yG(b@rppR%zz^tNN_bj3p;ggO$ z6O3k0sSZsx@TRQyVqgtjrE2}+)J>6>jTygGiif1GN~LmXD2QCTRRdwD7jwK-3AIU= zg-&9kkzSDe)?cJ1EqFRAUa9Ew4v5e#8db8U2PCq<{8nF#w00|DNgP*XGOk|{>Tb%a zU!#Vw)E5NQ8P_374Fy_z7j=Tc*U*XTSfUv*6_b^Y>u*;0SwkqQf03p;`}Hoa3*gol z1p>VQD7s`HaFW2j{szXO%qIn`9YuhSQ0$uRVlH43|0|MuMR*%>z-S}%+`H%`pP4Iw z0HSpQK;_tNXkDoh-T^Wi9hCw@fiM-pj6nu<<1`DCTc%K8Vz$u71br+zmd1}O&ML?c zNB_yrr{CSNe_T^u{jCimJA7dy*3d%_LvYrcofSqFuAmn(G|Mub;_CaT-A@Ny7^@7R z#twTexcja02~?U*(fx*&{cvBB#S zFDRKNavFAp{ay;y--Rvf-^j%E_h1N64$0|eB~<@*RR4}<-kude-E0%6SRaJ@cD`Ad zA?rh=`aD@KC5w-xoumhD5L46_tx1!|XzIx4;U>3$rU0{)&1V74+S`K%c(4HX9`MY@ z=~pY4_1XN&p318>aBXXaD-jgsb**yEGgHM5-G$Z5wPeZdV->|8a4PkCpi(&@a)`|%W2Z|3Er6yqrf2a8VK8dwdHItAjIbqD~I5ae^SSJZ!A5W`+grKkcb@Rpo~k9L{B=R z6>*KU04HEBk5#f1Y-{$&r|nX)hlPY{au56svhJU9br-excq*>3meh#%Xj#Qr+N8&BZ&Ueni3Un7aQYD+1Ph}{H&es;03D#f6UqwlQgdX zII90ND`PI(yJ9K}H8ieC#$;m}rd{TsBx5+BU|hdWJ#qa{Fe;ODW(wCEpYArn^9Vo! z(TcvW6{}Qd%M7|F=xM2$1(?saPkf|`kH@9Hrl=D&k{JDu8)#a}iveEyeK;U>vY7^O|inw$MwoCFhXna64NvsC7q zRme5F?4b#8wz05{UzF3W{+4tDwuqkbIVJ~m3i<(MBd)2xMafPoqiW^_%h^Iyu5^c} zLJ1-cMVA1IRG>DfuP4AY)q-3H8xf(VjEvKZ8Nw_YwJ;sm@{?uYc$h(L3$x`cxn6gV zyxz__wWg<5S=VHw%LK&`-N*W(JH94wItzPP44eE4(>(@sw|tE8a!#f$vx7pI5E*Ox z77)or))9h+2(sNGCK$`0Q9j7}GDNTYzS9kf+cD_Uk_aIRQ>IfK#a{gae^Ano=bf&d zx4L#-t=6{UYPS-&l<0#c>EQ*JHou8Q&%ES*9Eadis72-i)uT${rRbuZ7*LCy2vxoy zh8eNJB?ZS^V@tNNB^rZ}JN?@NlC4J2O4{m+B{IfvWM^D~1y*jP>`w4n=np!9Lq{xF z=mqjdG-0A2l$ZvVup^?2aG*Sz@?NrZkC*tZRB4;jPHWGOH+FNE z0Q%$QLR@>hn{f3F!ez?b8suaFk+B>>Q!=bsy&OphmJ2u?M6dQ3-LeUlbgt5dG< zDTWafLKTr*eKSe6r8XBvWD;99DWG)SdP$j<08AnUbta8y9fASAJoxD#C+C+1$BQ8% z+He_Tl^rgOOuNsObsH=t*@&C*g?8k5+!?IHU9^aW$)1t@&0>#P?Z_ZMq;>LfD(PW$ zvsi{Z@LiCA6m*b)Q{OSBI7OoaeNBCRfpdiU+l{gNwQo3B~)#~O$*#$sqv1BCy zH?XbX4`t!XODx$rn1mffJ?HQ`mWUp43tGG*z@VWs^_>2eag9tVQ2iz~KwF7vJqP^? z1x&77A~Ce5F_KBjvrx#wzC-dGVvPGmyg0>p2!}3icDoZQH#Ey#rr0D+woUb&ZutnS z@9+nhR0cjO)q{4TJp51Ly!BldHR~Wh_MeFZ*yS0P{yZfp{XsW`o{_{1g)D<`h`^qp zBNq?-j+f_f^ZT)+G9HppFVDr*e}QvR_|FL`0fVy}$;CUdcKP$olwYtHD%tPr<<>DcMb zF0G`OziRDaIE@hICTY>~TS=Ni+8DuMgTEE$-EgoD^@1g$M(Hdjj-0bRzo?m^o32D84k zilio2hlnFs*@LdM%F1|hZ?-O=gII^ecA(P<&}q^eK#HU_!Gl^`h!3G@3GI3(22A~} zW^%%$)%VFmCeT{eYux9V;*l%dAjUoSr;aS1nYqL!yj^7$J(FwPJZ((H<3^SA+rBFQ z?0ThlsiuDI=%DssZ%G1cJ11Aa%gPZj?+UYcW&D@G&6c~^z`-@#&?a6 zad18Fne4XVv0;wZJ?5ED5AWYQ)%YT=t;u(E?RjZzctq>rTN+u(waxoy&dv6!Or?=i z8Dn7_SgZ+XYt=Aj=#DA>Q_pY(?EVYq8()gV9eG^xY+;u^bLd%t>Ieb{kj+Cs^~^(m z^soQJg(v>azBhLMgU{Fg^GAQG0*~G|ec=4;X};EBc6#FS#o_a_3)5Vd zr|SZz+iAEm%Gbh8+e@ZbWDH+CebShJN4x3Ie^I!S#@gRMYQS;z+oeb6xoTKnCV2VO zg-f%u!>75FT|XafHkF5L=+}>5Q$RClFJ!ot^J?wXkbD>pq^(XD+~fQ|i)2)EG$;9~ zWcVbC;bvw&)bX_0Yd-+8kNXPt6W7&7x->{X-|qOcpR3&tD_PAqmqgf~4xW;^)}Kd- zc+{#RkLfX59mUmgM*ZADZH5DHx??~GbamjaafaSP{6R;RN>hZ`>0cm(x)>cU=35{lJS3&go~88g=W0F1fk@Rvc!AMm>~Cu}weKqqcQ3 zMRL9$INb}UL+knkztT^UlHRYUy0>EYH0yDfaio`dD1RHr^v3u{U(#kDu%b+QV}cH8 z>!Udi)0?$5%z;GR_Mo3>a~t*OqAlI?$K|N>>LPdwdwpC;{ac+@G1pN}t7%aIM}3%v zX@H-D7Ds(XN_A-@)Iv(9^c3jL>C%epLzd3&p!8`dCn`33eDivQ&xoaOd-;`AZl&=~ prVww{f$a+1sgD>mN2Xau$3Fib`uUNE>zf}wwfF0v|NkiPzX2TXAw&QG literal 0 HcmV?d00001 diff --git a/Src/Asp.Net/OracleTest/PerformanceTesting/PerformanceBase.cs b/Src/Asp.Net/OracleTest/PerformanceTesting/PerformanceBase.cs new file mode 100644 index 000000000..cba502561 --- /dev/null +++ b/Src/Asp.Net/OracleTest/PerformanceTesting/PerformanceBase.cs @@ -0,0 +1,30 @@ +using SyntacticSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.PerformanceTesting +{ + public class PerformanceBase + { + public int count = 100; + public void Execute(string title, Action fun) + { + PerformanceTest ptef = new PerformanceTest(); + ptef.SetCount(count);//执行count次 + ptef.Execute( + i => + { + fun(); + + }, + res => + { + Console.WriteLine(string.Format("Execute {0} time,{1}{2}", count, title, res)); + }); + + } + } +} diff --git a/Src/Asp.Net/OracleTest/PerformanceTesting/SqlSugarPerformance.cs b/Src/Asp.Net/OracleTest/PerformanceTesting/SqlSugarPerformance.cs new file mode 100644 index 000000000..5299a8813 --- /dev/null +++ b/Src/Asp.Net/OracleTest/PerformanceTesting/SqlSugarPerformance.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using OrmTest.Models; + +namespace OrmTest.PerformanceTesting +{ + public class SqlSugarPerformance : PerformanceBase + { + public SqlSugarPerformance(int eachCount) + { + this.count = eachCount; + } + public void Select() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() + { + ConnectionString = Config.ConnectionString, + DbType = DbType.SqlServer, + IsAutoCloseConnection = false + }); + db.IgnoreColumns.Add("TestId", "Student"); + db.Queryable().Select(it => new ViewModelStudent2 { Name = it.Name, Student = it }).ToList(); + base.Execute("sqlsuagr", () => + { + var test = db.Queryable().Select(it => new ViewModelStudent2 { Name = it.Name, Student = it }).ToList(); + }); + db.Close(); + } + } +} diff --git a/Src/Asp.Net/OracleTest/Program.cs b/Src/Asp.Net/OracleTest/Program.cs new file mode 100644 index 000000000..b73a61cca --- /dev/null +++ b/Src/Asp.Net/OracleTest/Program.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Linq.Expressions; +using SqlSugar; +using OrmTest.Models; +using System.Data.SqlClient; +using OrmTest.UnitTest; +using OrmTest.PerformanceTesting; + +namespace OrmTest +{ + class Program + { + static void Main(string[] args) + { + // /***Unit Test***/ + new Select(1).Init(); + new Field(1).Init(); + new Where(1).Init(); + new Method(1).Init(); + new JoinQuery(1).Init(); + new SingleQuery(1).Init(); + new SelectQuery(1).Init(); + new AutoClose(1).Init(); + new Insert(1).Init(); + new Delete(1).Init(); + new Update(1).Init(); + new Mapping(1).Init(); + new DataTest(1).Init(); + new EnumTest(1).Init(); + /***Performance Test***/ + new SqlSugarPerformance(100).Select(); + + /***Demo***/ + OrmTest.Demo.Query.Init(); + OrmTest.Demo.Insert.Init(); + OrmTest.Demo.Delete.Init(); + OrmTest.Demo.Update.Init(); + OrmTest.Demo.DbFirst.Init(); + OrmTest.Demo.JoinSql.Init(); + OrmTest.Demo.Filter.Init(); + OrmTest.Demo.ComplexModel.Init(); + OrmTest.Demo.CodeFirst.Init(); + } + } +} diff --git a/Src/Asp.Net/OracleTest/Properties/AssemblyInfo.cs b/Src/Asp.Net/OracleTest/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..77f29f118 --- /dev/null +++ b/Src/Asp.Net/OracleTest/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OracleTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OracleTest")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4177d054-d113-4f8a-9e01-642e072f9c87")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Src/Asp.Net/OracleTest/UnitTest/DataTest.cs b/Src/Asp.Net/OracleTest/UnitTest/DataTest.cs new file mode 100644 index 000000000..790df43b4 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/DataTest.cs @@ -0,0 +1,72 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.UnitTest +{ + public class DataTest : UnitTestBase + { + private DataTest() { } + public DataTest(int eachCount) + { + this.Count = eachCount; + } + + public void Init() + { + var db = GetInstance(); + db.DbMaintenance.TruncateTable("DataTestInfo"); + var insertObject = new DataTestInfo() + { + Datetime1 = DateTime.Now, + Datetime2 = DateTime.Now, + Decimal1 = 1, + Decimal2 = 2, + Float1 = 3, + Float2 = 4, + Guid1 = Guid.Empty, + Guid2 = null, + Image1 = new byte[] { 1, 2 }, + Image2 = new byte[] { 2, 3 }, + Int2 = 6, + Money1 = 7, + Money2 = 8, + Varbinary1 = new byte[] { 4, 5 }, + Varbinary2 = null, + String = "string" + }; + var id = db.Insertable(insertObject).ExecuteReutrnIdentity(); + var data = db.Queryable().InSingle(id); + if ( + insertObject.Datetime1.ToString("yyyy-MM-dd HH:mm:ss") != data.Datetime1.ToString("yyyy-MM-dd HH:mm:ss") || + insertObject.Decimal1 != data.Decimal1 || + insertObject.Float1 != data.Float1 || + insertObject.Float2 != data.Float2 || + insertObject.Int2 != data.Int2 || + insertObject.Money1 != data.Money1 || + string.Join(",", insertObject.Varbinary1) != string.Join(",", data.Varbinary1) || + insertObject.String != data.String) + { + throw new Exception("DataTest Error"); + } + data.Float1= data.Float1+1; + db.Updateable(data).ExecuteCommand(); + data = db.Queryable().InSingle(id); + if ( + insertObject.Datetime1.ToString("yyyy-MM-dd HH:mm:ss") != data.Datetime1.ToString("yyyy-MM-dd HH:mm:ss") || + insertObject.Decimal1 != data.Decimal1 || + (insertObject.Float1+1) != data.Float1 || + insertObject.Float2 != data.Float2 || + insertObject.Int2 != data.Int2 || + insertObject.Money1 != data.Money1 || + string.Join(",", insertObject.Varbinary1) != string.Join(",", data.Varbinary1) || + insertObject.String != data.String) + { + throw new Exception("DataTest Error"); + } + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/DataTest2.cs b/Src/Asp.Net/OracleTest/UnitTest/DataTest2.cs new file mode 100644 index 000000000..83e2818d9 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/DataTest2.cs @@ -0,0 +1,39 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.UnitTest +{ + public class DataTest2 : UnitTestBase + { + public interface IEntity { + T ID { get; set; } + } + public abstract class Entity : IEntity + { + public virtual T ID { get; set; } + } + public class MyModel: Entity + { + public override int ID { get; set; } + } + private DataTest2() { } + public DataTest2(int eachCount) + { + this.Count = eachCount; + } + + public void Init() + { + var db = GetInstance(); + var t1 = db.Queryable().AS("Student").ToList(); + } + public SqlSugarClient GetInstance() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); + return db; + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Delete.cs b/Src/Asp.Net/OracleTest/UnitTest/Delete.cs new file mode 100644 index 000000000..0243b5596 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Delete.cs @@ -0,0 +1,61 @@ +using OrmTest.Models; +using OrmTest.UnitTest; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest +{ + public class Delete : UnitTestBase + { + private Delete() { } + public Delete(int eachCount) + { + this.Count = eachCount; + } + + public void Init() + { + var db = GetInstance(); + //by entity + var t1= db.Deleteable().Where(new Student() { Id = 1 }).ToSql(); + base.Check(@"DELETE FROM [STudent] WHERE [Id] IN ('1') ", + null, + t1.Key, + null, "Delte t1 error" + ); + //use lock + var t2 = db.Deleteable().With(SqlWith.RowLock).ToSql(); + base.Check(@"DELETE FROM [STudent] WITH(ROWLOCK) ", + null, + t2.Key, + null, "Delte t2 error" + ); + + //by primary key + var t3 = db.Deleteable().In(1).ToSql(); + base.Check(@"DELETE FROM [STudent] WHERE [Id] IN ('1') ", + null, + t3.Key, + null, "Delte tt error" + ); + //by primary key array + var t4 = db.Deleteable().In(new int[] { 1,2}).ToSql(); + base.Check(@"DELETE FROM [STudent] WHERE [Id] IN ('1','2') ", null, t4.Key, null, "Update t4 error"); + + //by expression + var t5 = db.Deleteable().Where(it=>it.Id==1).ToSql(); + base.Check(@"DELETE FROM [STudent] WHERE ( [ID] = @Id0 ) ", new List() { + new SugarParameter("@Id0",1) + }, t5.Key, t5.Value, "Delte t5 error"); + + var t6 = db.Deleteable().Where("id=@id",new { id=1}).ToSql(); + base.Check(@"DELETE FROM [STudent] WHERE id=@id", new List() { + new SugarParameter("@id",1) + }, t6.Key, t6.Value, "Delte t6 error"); + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/EnumTest.cs b/Src/Asp.Net/OracleTest/UnitTest/EnumTest.cs new file mode 100644 index 000000000..26515076b --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/EnumTest.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OrmTest.Demo; +using OrmTest.Models; + +namespace OrmTest.UnitTest +{ + public class EnumTest : UnitTestBase + { + private EnumTest() { } + public EnumTest(int eachCount) + { + this.Count = eachCount; + } + public void Init() + { + + var db = GetInstance(); + var shoolValue = SchoolEnum.HarvardUniversity; + var enums = new SchoolEnum[] { shoolValue, SchoolEnum.UniversityOfOxford }; + var list = db.Queryable().AS("student").Where(it => it.SchoolId == shoolValue).ToList(); + + var x = new StudentEnum() + { + Name = shoolValue.ToString(), + SchoolId = shoolValue + }; + var x2 = db.Queryable().AS("student").Where(it => enums.Contains(it.SchoolId)).ToSql(); + var id= db.Insertable(x).AS("student").ExecuteReutrnIdentity(); + var data = db.Queryable().AS("student").InSingle(id); + shoolValue = SchoolEnum.UniversityOfOxford; + var sql= db.Updateable().AS("student").UpdateColumns(it=>new StudentEnum() { Name="a" , SchoolId= shoolValue }).Where(it=>it.Id==id).ToSql(); + + var sql2 = db.Updateable().AS("student").UpdateColumns(it => new StudentEnum() { Name = "a", SchoolId = SchoolEnum.UniversityOfOxford }).Where(it => it.Id == id).ToSql(); + } + } +} \ No newline at end of file diff --git a/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Field.cs b/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Field.cs new file mode 100644 index 000000000..9f7384f0e --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Field.cs @@ -0,0 +1,51 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class Field : UnitTestBase + { + private Field() { } + public Field(int eachCount) + { + this.Count = eachCount; + } + internal void Init() + { + base.Begin(); + for (int i = 0; i < base.Count; i++) + { + FieldSingle(); + FieldMultiple(); + } + base.End("Filed Test"); + } + private void FieldSingle() + { + Expression> exp = it => it.Name; + ExpressionContext expContext = GetContext(); + expContext.Resolve(exp, ResolveExpressType.FieldSingle); + var selectorValue = expContext.Result.GetString(); + Check(selectorValue, null, expContext.GetTranslationColumnName("Name"), null, "FieldSingle error"); + } + private void FieldMultiple() + { + Expression> exp = it => it.Name; + ExpressionContext expContext = GetContext(); + expContext.Resolve(exp, ResolveExpressType.FieldMultiple); + var selectorValue = expContext.Result.GetString(); + Check(selectorValue, null, expContext.GetTranslationColumnName("it.Name"), null, "FieldMultiple error"); + } + + public ExpressionContext GetContext() + { + return new SqlServerExpressionContext();//可以更换 + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Method.cs b/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Method.cs new file mode 100644 index 000000000..25bf15df7 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Method.cs @@ -0,0 +1,709 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class Method : UnitTestBase + { + private Method() { } + public Method(int eachCount) + { + this.Count = eachCount; + } + internal void Init() + { + base.Begin(); + for (int i = 0; i < base.Count; i++) + { + + //Native methods + ExtendContainsArray(); + ConvetToString(); + ExtendToString(); + ExtendSubstring(); + ExtendDate(); + + //SqlFun methods + MappingColumn(); + IIF(); + IIF2(); + #region StringIsNullOrEmpty + HasValue(); + HasNumber(); + StringIsNullOrEmpty(); + StringIsNullOrEmpty2(); + StringIsNullOrEmpty3(); + StringIsNullOrEmpty4(); + StringIsNullOrEmpty5(); + #endregion + ToUpper(); + ToLower(); + Trim(); + Contains(); + Contains2(); + Contains3(); + ContainsArray(); + StartsWith(); + EndsWith(); + Between(); + Equals(); + Equals_2(); + DateIsSameByDay(); + DateIsSameByType(); + DateAddDay(); + DateAddByType(); + DateValue(); + ToInt32(); + ToInt64(); + ToDate(); + Tostring(); + ToDecimal(); + ToGuid(); + ToDouble(); + ToBool(); + Substring(); + Replace(); + Length(); + Time(); + } + base.End("Method Test"); + } + + private void ExtendToString() + { + Expression> exp = it => it.Id.ToString() == "a"; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST([Id] AS NVARCHAR(MAX)) = @Const0 )", new List() { + new SugarParameter("@Const0","a") + }, "ExtendToString error"); + } + + private void ConvetToString() + { + Expression> exp = it => Convert.ToString(it.Id) == "a"; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST([Id] AS NVARCHAR(MAX)) = @Const0 )", new List() { + new SugarParameter("@Const0","a") + }, "ConvetToString error"); + } + + + private void Length() + { + Expression> exp = it => SqlFunc.Length("aaaa") > 1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(LEN(@MethodConst0) > @Const1 )", new List() { + new SugarParameter("@MethodConst0","aaaa"),new SugarParameter("@Const1",1) + }, "Length error"); + + Length2(); + Length3(); + } + + private void Length2() + { + Expression> exp = it => it.Name.Length > 1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(LEN([Name])> @Length1 )", new List() { + new SugarParameter("@Length1",1) + }, "Length2 error"); + } + + private void Length3() + { + Expression> exp = it => it.Name.Length > "a".Length; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(LEN([Name])> @Length1 )", new List() { + new SugarParameter("@Length1",1) + }, "Length3 error"); + } + + private void Time() + { + TimeSpan s = TimeSpan.Parse("11:22:22"); + Expression> exp = it => SqlFunc.ToTime("11:12:59")==s; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS TIME) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","11:12:59"),new SugarParameter("@Const1",s) + }, "Time error"); + } + + + private void Replace() + { + var x2 = Guid.NewGuid(); + Expression> exp = it => SqlFunc.Replace("aaaa", "a", "1") == "a"; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(REPLACE(@MethodConst0,@MethodConst1,@MethodConst2) = @Const3 )", new List() { + new SugarParameter("@MethodConst0","aaaa"), new SugarParameter("@MethodConst1","a") , new SugarParameter("@MethodConst2","1"),new SugarParameter("@Const3","a") + }, "Replace error"); + } + + private void Substring() + { + var x2 = Guid.NewGuid(); + Expression> exp = it => SqlFunc.Substring("aaaa", 0, 2) == "a"; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(SUBSTRING(@MethodConst0,1 + @MethodConst1,@MethodConst2) = @Const3 )", new List() { + new SugarParameter("@MethodConst0","aaaa"), new SugarParameter("@MethodConst1",0) , new SugarParameter("@MethodConst2",2),new SugarParameter("@Const3","a") + }, "Substring error"); + } + private void ExtendSubstring() + { + var x2 = Guid.NewGuid(); + Expression> exp = it =>"aaaa".Substring(0, 2)== "a"; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(SUBSTRING(@MethodConst0,1 + @MethodConst1,@MethodConst2) = @Const3 )", new List() { + new SugarParameter("@MethodConst0","aaaa"), new SugarParameter("@MethodConst1",0) , new SugarParameter("@MethodConst2",2),new SugarParameter("@Const3","a") + }, "Substring error"); + } + + + private void ToBool() + { + var x2 = Guid.NewGuid(); + Expression> exp = it => SqlFunc.ToBool("true") == true; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS BIT) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","true"),new SugarParameter("@Const1",(bool)true) + }, "ToBool error"); + } + + private void ToDouble() + { + var x2 = Guid.NewGuid(); + Expression> exp = it => SqlFunc.ToDouble("2") == 2; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS FLOAT) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","2"),new SugarParameter("@Const1",(Double)2) + }, "ToDouble error"); + } + + private void ToGuid() + { + var x2 = Guid.NewGuid(); + Expression> exp = it => SqlFunc.ToGuid("A94027A3-476E-478D-8228-F4054394B874") == x2; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS UNIQUEIDENTIFIER) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","A94027A3-476E-478D-8228-F4054394B874"),new SugarParameter("@Const1",x2) + }, "ToGuid error"); + } + + private void ToDecimal() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.ToDecimal("22") == 1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS MONEY) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","22"),new SugarParameter("@Const1",(decimal)1) + }, "ToDecimal error"); + } + + private void Tostring() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.ToString("2015-1-1") == "a"; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS NVARCHAR(MAX)) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","2015-1-1"),new SugarParameter("@Const1","a") + }, "Tostring error"); + } + + private void ToDate() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.ToDate("2015-1-1") == x2; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS DATETIME) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","2015-1-1"),new SugarParameter("@Const1",x2) + }, "ToDate error"); + } + private void ExtendDate() + { + var x2 = DateTime.Now; + Expression> exp = it => Convert.ToDateTime("2015-1-1") == x2; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS DATETIME) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","2015-1-1"),new SugarParameter("@Const1",x2) + }, "ExtendDate error"); + } + + private void ToInt64() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.ToInt64("3") == 1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS BIGINT) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","3"),new SugarParameter("@Const1",(Int64)1) + }, "ToInt64 error"); + } + + private void ToInt32() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.ToInt32("3") == 1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(CAST(@MethodConst0 AS INT) = @Const1 )", new List() { + new SugarParameter("@MethodConst0","3"),new SugarParameter("@Const1",1) + }, "ToInt32 error"); + } + + private void DateValue() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.DateValue(x2, DateType.Year) == 1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ((@MethodConst1(@MethodConst0)) = @Const2 ) ", new List() { + new SugarParameter("@MethodConst0",x2),new SugarParameter("@MethodConst1",DateType.Year),new SugarParameter("@Const2",1) + }, "DateValue error"); + } + + private void StartsWith() + { + Expression> exp = it => SqlFunc.StartsWith(it.Name, "a"); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ([Name] like @MethodConst0+'%') ", new List() { + new SugarParameter("@MethodConst0","a") + }, "StartsWith error"); + } + private void EndsWith() + { + Expression> exp = it => SqlFunc.EndsWith(it.Name, "a"); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ([Name] like '%'+@MethodConst0) ", new List() { + new SugarParameter("@MethodConst0","a") + }, "EndsWith"); + } + private void Between() + { + Expression> exp = it => SqlFunc.Between(it.Name, 1, 2); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ([Name] BETWEEN @MethodConst0 AND @MethodConst1) ", new List() { + new SugarParameter("@MethodConst0",1),new SugarParameter("@MethodConst1",2), + }, "Between error"); + } + + private void DateAddByType() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.DateAdd(x2, 11, DateType.Millisecond) == x2; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "((DATEADD(@MethodConst2,@MethodConst1,@MethodConst0)) = @Const3 )", new List() { + new SugarParameter("@MethodConst0",x2),new SugarParameter("@MethodConst1",11),new SugarParameter("@Const3",x2), + new SugarParameter("@MethodConst2",DateType.Millisecond) + }, "DateAddByType error"); + } + private void DateAddDay() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.DateAdd(x2, 1) == x2; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "((DATEADD(day,@MethodConst1,@MethodConst0)) = @Const2 )", new List() { + new SugarParameter("@MethodConst0",x2),new SugarParameter("@MethodConst1",1),new SugarParameter("@Const2",x2) + }, "DateAddDay error"); + + DateAddDay2(); + DateAddDay3(); + } + + private void DateAddDay2() + { + var x2 = DateTime.Now; + Expression> exp = it =>it.Datetime2.Value.AddHours(10) == x2; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "((DATEADD(@Const0,@MethodConst1,[Datetime2])) = @Const2 )", new List() { + new SugarParameter("@Const0",DateType.Hour.ToString()),new SugarParameter("@MethodConst1",10) + ,new SugarParameter("@Const2",x2) + }, "DateAddDay2 error"); + } + + private void DateAddDay3() + { + var x2 = DateTime.Now; + Expression> exp = it => x2.AddHours(1) == x2; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "((DATEADD(@Const0,@MethodConst2,@MethodConst1)) = @Const3 )", new List() { + new SugarParameter("@Const0",DateType.Hour.ToString()),new SugarParameter("@MethodConst2",1),new SugarParameter("@MethodConst1",x2) + ,new SugarParameter("@Const3",x2) + }, "DateAddDay3 error"); + } + + private void DateIsSameByType() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.DateIsSame(x2, x2, DateType.Millisecond); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " (DATEDIFF(@MethodConst2,@MethodConst0,@MethodConst1)=0) ", new List() { + new SugarParameter("@MethodConst0",x2),new SugarParameter("@MethodConst1",x2), + new SugarParameter("@MethodConst2",DateType.Millisecond) + }, "DateIsSameByType error"); + } + private void DateIsSameByDay() + { + var x2 = DateTime.Now; + Expression> exp = it => SqlFunc.DateIsSame(x2, x2); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(DATEDIFF(day,@MethodConst0,@MethodConst1)=0) ", new List() { + new SugarParameter("@MethodConst0",x2),new SugarParameter("@MethodConst1",x2) + }, "DateIsSameDay error"); + } + + private void Equals() + { + Expression> exp = it => SqlFunc.Equals(it.Name, "a"); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ([Name] = @MethodConst0) ", new List() { + new SugarParameter("@MethodConst0","a") + }, "Equals1 error"); + + + Expression> exp2 = it => SqlFunc.Equals("a", it.Name); + SqlServerExpressionContext expContext2 = new SqlServerExpressionContext(); + expContext2.Resolve(exp2, ResolveExpressType.WhereSingle); + var value2 = expContext2.Result.GetString(); + var pars2 = expContext2.Parameters; + base.Check(value2, pars2, " (@MethodConst0 = [Name]) ", new List() { + new SugarParameter("@MethodConst0","a") + }, "Equals2 error"); + } + private void Equals_2() + { + Expression> exp = it => SqlFunc.Equals(it.Name, it.Name); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ([Name] = [Name]) ", new List() { + new SugarParameter("@MethodConst0","a") + }, "Equals1 error"); + + + Expression> exp2 = it => SqlFunc.Equals("a", "a2"); + SqlServerExpressionContext expContext2 = new SqlServerExpressionContext(); + expContext2.Resolve(exp2, ResolveExpressType.WhereSingle); + var value2 = expContext2.Result.GetString(); + var pars2 = expContext2.Parameters; + base.Check(value2, pars2, " (@MethodConst0 = @MethodConst1) ", new List() { + new SugarParameter("@MethodConst0","a"),new SugarParameter("@MethodConst1","a2") + }, "Equals2 error"); + } + + private void Contains() + { + Expression> exp = it => SqlFunc.Contains(it.Name, "a"); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ([Name] like '%'+@MethodConst0+'%') ", new List() { + new SugarParameter("@MethodConst0","a") + }, "Contains error"); + } + private void Contains2(string name="a") + { + Expression> exp = it => SqlFunc.Contains(it.Name, name); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ([Name] like '%'+@MethodConst0+'%') ", new List() { + new SugarParameter("@MethodConst0","a") + }, "Contains2 error"); + } + private void Contains3(string name = "a") + { + Expression> exp = it => !SqlFunc.Contains(it.Name, name)&&it.Id==1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(NOT ([Name] like '%'+@MethodConst0+'%') AND( [Id] = @Id1 ))", new List() { + new SugarParameter("@MethodConst0","a"), + new SugarParameter("@Id1",1) + }, "Contains3 error"); + } + + private void ExtendContainsArray() { + var array = new string[] { "1", "2" }.ToList(); + Expression> exp = it => array.Contains(it.Name); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, null, " ([Name] IN ('1','2')) ", null, "Contains2 error"); + } + + private void ContainsArray() + { + string[] array = new string[] { "1", "2" }; + Expression> exp = it => SqlFunc.ContainsArray(array, it.Name); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, null, " ([Name] IN ('1','2')) ", null, "Contains2 error"); + } + + private void Trim() + { + Expression> exp = it => SqlFunc.Trim(" a") == it.Name; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "((rtrim(ltrim(@MethodConst0))) = [Name] )", new List() { + new SugarParameter("@MethodConst0"," a") + }, "Trim error"); + } + + private void ToUpper() + { + Expression> exp = it => "a" == SqlFunc.ToUpper(it.Id); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( @Const0 = (UPPER([Id])) )", new List() { + new SugarParameter("@Const0","a") + }, "ToUpper error"); + } + private void ToLower() + { + Expression> exp = it => "a" == SqlFunc.ToLower(it.Id); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( @Const0 = (LOWER([Id])) )", new List() { + new SugarParameter("@Const0","a") + }, "ToLower error"); + } + + #region StringIsNullOrEmpty + private void StringIsNullOrEmpty() + { + Expression> exp = it => it.Id > 2 || SqlFunc.IsNullOrEmpty(it.Id); ; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( [Id] > @Id0 ) OR ( [Id]='' OR [Id] IS NULL ))", new List() { + new SugarParameter("@Id0",2) + }, "StringIsNullOrEmpty error"); + } + private void StringIsNullOrEmpty2() + { + Expression> exp = it => 2 == it.Id || SqlFunc.IsNullOrEmpty(true); ; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( @Id0 = [Id] ) OR ( @MethodConst1='' OR @MethodConst1 IS NULL ))", new List() { + new SugarParameter("@MethodConst1",true), + new SugarParameter("@Id0",2) + }, "StringIsNullOrEmpty2 error"); + } + private void StringIsNullOrEmpty3() + { + int a = 1; + Expression> exp = it => 2 == it.Id || SqlFunc.IsNullOrEmpty(a); ; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( @Id0 = [Id] ) OR ( @MethodConst1='' OR @MethodConst1 IS NULL ))", new List() { + new SugarParameter("@MethodConst1",1), + new SugarParameter("@Id0",2) + }, "StringIsNullOrEmpty3 error"); + } + private void StringIsNullOrEmpty4() + { + WhereConst.name = "xx"; + Expression> exp = it => 2 == it.Id || SqlFunc.IsNullOrEmpty(WhereConst.name); ; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( @Id0 = [Id] ) OR ( @MethodConst1='' OR @MethodConst1 IS NULL ))", new List() { + new SugarParameter("@MethodConst1","xx"), + new SugarParameter("@Id0",2) + }, "StringIsNullOrEmpty4 error"); + } + private void StringIsNullOrEmpty5() + { + WhereConst.name = "xx"; + Expression> exp = it => !SqlFunc.IsNullOrEmpty(WhereConst.name); ; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "NOT( @MethodConst0='' OR @MethodConst0 IS NULL )", new List() { + new SugarParameter("@MethodConst0","xx") + }, "StringIsNullOrEmpty5 error"); + } + #endregion + + private void HasValue() + { + Expression> exp = it => SqlFunc.HasValue(it.Name); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Name]<>'' AND [Name] IS NOT NULL )", new List() + { + + }, "HasValue error"); + } + + private void HasNumber() + { + Expression> exp = it => SqlFunc.HasNumber(it.Id); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Id]>0 AND [Id] IS NOT NULL )", new List() + { + + + }, "HasNumber error"); + } + private void MappingColumn() { + Expression> exp = it => SqlFunc.MappingColumn(it.Id,"Name") == 1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(Name = @Const1 )", new List() + { + new SugarParameter("@Const1",1) + }, "MappingColumn error"); + } + private void IIF() + { + Expression> exp = it => SqlFunc.IIF(it.Id == 1, 1, 2)==1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( CASE WHEN ( [Id] = @Id0 ) THEN @MethodConst1 ELSE @MethodConst2 END ) = @Const3 )", new List() + { + new SugarParameter("@Id0",1), + new SugarParameter("@MethodConst1",1), + new SugarParameter("@MethodConst2",2), + new SugarParameter("@Const3",1) + }, "IIF error"); + } + + private void IIF2() + { + Expression> exp = it => SqlFunc.IIF(SqlFunc.Contains(it.Name,"a"), 1, 2)==1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( CASE WHEN ([Name] like '%'+@MethodConst0+'%') THEN @MethodConst1 ELSE @MethodConst2 END ) = @Const3 )", new List() + { + new SugarParameter("@MethodConst0","a"), + new SugarParameter("@MethodConst1",1), + new SugarParameter("@MethodConst2",2), + new SugarParameter("@Const3",1) + }, "IIF2 error"); + } + } +} + diff --git a/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Select.cs b/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Select.cs new file mode 100644 index 000000000..f99a76133 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Select.cs @@ -0,0 +1,186 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class Select : UnitTestBase + { + private Select() { } + public Select(int eachCount) + { + this.Count = eachCount; + } + internal void Init() + { + base.Begin(); + for (int i = 0; i < base.Count; i++) + { + single(); + single2(); + single3(); + single4(); + single5(); + Multiple(); + Multiple2(); + singleDynamic(); + MultipleDynamic(); + } + base.End("Select Test"); + } + + private void Multiple() + { + Expression> exp = (it, school) => new Student() { Name = "a", Id = it.Id, SchoolId = school.Id, TestId = it.Id + 1 }; + ExpressionContext expContext = new ExpressionContext(); + expContext.IsSingle = false; + expContext.Resolve(exp, ResolveExpressType.SelectMultiple); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + selectorValue, + pars, + @" @constant0 AS [Name] , [it].[Id] AS [Id] , [school].[Id] AS [SchoolId] , ( [it].[Id] + @Id1 ) AS [TestId] ", + new List(){ + new SugarParameter("@constant0","a"), + new SugarParameter("@Id1",1) + }, + "Select.Multiple Error"); + } + private void Multiple2() + { + Expression> exp = (it, school) => new ViewModelStudent3() { SchoolName=school.Name,Id=SqlFunc.GetSelfAndAutoFill(it.Id) }; + ExpressionContext expContext = new ExpressionContext(); + expContext.IsSingle = false; + expContext.Resolve(exp, ResolveExpressType.SelectMultiple); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + selectorValue, + pars, + @" [school].[Name] AS [SchoolName] ,it.*", + new List(){ + + }, + "Select.Multiple Error"); + } + + + private void MultipleDynamic() + { + Expression> exp = (it, school) => new { Name = "a", Id = it.Id / 2, SchoolId = school.Id }; + ExpressionContext expContext = new ExpressionContext(); + expContext.IsSingle = false; + expContext.Resolve(exp, ResolveExpressType.SelectMultiple); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + selectorValue, + pars, + @" @constant0 AS [Name] , ( [it].[Id] / @Id1 ) AS [Id] , [school].[Id] AS [SchoolId] ", + new List(){ + new SugarParameter("@constant0","a"), + new SugarParameter("@Id1", 2)}, + "Select.MultipleDynamic Error"); + } + private void single() + { + int p = 1; + Expression> exp = it => new Student() { Name = "a", Id = it.Id, SchoolId = p,TestId=it.Id+11 }; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.SelectSingle); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + selectorValue, + pars, + @" @constant0 AS [Name] , [Id] AS [Id] , @constant1 AS [SchoolId] , ( [Id] + @Id2 ) AS [TestId] ", + new List(){ + new SugarParameter("@constant0","a"), + new SugarParameter("@constant1",1), + new SugarParameter("@Id2",11 ) }, + "Select.single Error"); + } + private void single2(int p=1) + { + Expression> exp = it => new Student() { Name = "a", Id = it.Id, SchoolId = p, TestId = it.Id + 11 }; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.SelectSingle); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + selectorValue, + pars, + @" @constant0 AS [Name] , [Id] AS [Id] , @constant1 AS [SchoolId] , ( [Id] + @Id2 ) AS [TestId] ", + new List(){ + new SugarParameter("@constant0","a"), + new SugarParameter("@constant1",1), + new SugarParameter("@Id2",11 ) }, + "Select.single Error"); + } + private void single3(int p = 1) + { + Expression> exp = it => new DataTestInfo() { Datetime1=DateTime.Now, String=it.Name}; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.SelectSingle); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + @" @constant0 AS [Datetime1] , [Name] AS [String] ", null,selectorValue,null, + "Select.single3 Error"); + } + + private void single4(int p = 1) + { + Expression> exp = it => it.CreateTime.HasValue; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.IsSingle = false; + expContext.Resolve(exp, ResolveExpressType.WhereMultiple); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + @"( [it].[CreateTime]<>'' AND [it].[CreateTime] IS NOT NULL )", null, selectorValue, null, + "Select.single4 Error"); + } + + private void single5() + { + var p =(DateTime?) DateTime.Now; + Expression> exp = it => p.HasValue; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.IsSingle = false; + expContext.Resolve(exp, ResolveExpressType.WhereMultiple); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + @"( @constant0<>'' AND @constant0 IS NOT NULL )", new List() { + new SugarParameter("@constant0",p) + }, selectorValue, pars, + "Select.single4 Error"); + } + + private void singleDynamic() + { + string a = "a"; + Expression> exp = it => new { x = it.Id, shoolid = 1, name = a,p=it.Id*2 }; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.SelectSingle); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + selectorValue, + pars, + @" [Id] AS [x] , @constant0 AS [shoolid] , @constant1 AS [name] , ( [Id] * @Id2 ) AS [p] ", + new List(){ + new SugarParameter("@constant0",1), + new SugarParameter("@constant1","a"), + new SugarParameter("@Id2",2)}, + "Select.singleDynamic Error"); + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Where.cs b/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Where.cs new file mode 100644 index 000000000..f6476cb51 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/ExpressionTest/Where.cs @@ -0,0 +1,387 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class Where : UnitTestBase + { + private Where() { } + public Where(int eachCount) + { + this.Count = eachCount; + } + internal void Init() + { + base.Begin(); + for (int i = 0; i < base.Count; i++) + { + + whereSingle23(); + whereSingle22(); + whereSingle21(); + whereSingle20(); + whereSingle19(); + whereSingle18(); + whereSingle17(); + whereSingle16(); + whereSingle15(); + whereSingle1(); + whereSingle2(); + whereSingle3(); + whereSingle4(); + whereSingle5(); + whereSingle6(); + whereSingle7(new Student() { Id = 1 }); + whereSingle8(new Student() { Id = 1 }); + whereSingle9(new Student() { Id = 1 }); + whereSingle10(); + whereSingle11(); + whereSingle12(); + whereSingle13(); + whereSingle14(); + whereSingle15(); + WhereMultiple1(); + WhereMultiple2(); + + } + base.End("Where Test"); + } + private void WhereMultiple1() + { + Expression> exp = it => it.Id > 1; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereMultiple); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [it].[Id] > @Id0 )", new List() { + new SugarParameter("@Id0",1) + }, "WhereMultiple1"); + } + private void WhereMultiple2() + { + string name = "a"; + WhereConst.name = "a1"; + Expression> exp = it => (it.Id > 1 && it.Name != name || it.Id == 1) || it.Name == WhereConst.name; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereMultiple); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " (((( [it].[Id] > @Id0 ) AND ( [it].[Name] <> @Name1 )) OR ( [it].[Id] = @Id2 )) OR ( [it].[Name] = @Name3 ))", new List() { + new SugarParameter("@Id0",1), + new SugarParameter("@Name1","a"), + new SugarParameter("@Id2",1), + new SugarParameter("@Name3","a1") + }, "WhereMultiple2"); + } + private void whereSingle1() + { + Expression> exp = it => it.Id > 1; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Id] > @Id0 )", new List() { + new SugarParameter("@Id0",1) + }, "whereSingle1"); + } + private void whereSingle2() + { + Expression> exp = it => 1 > it.Id; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( @Id0 > [Id] )", new List() { + new SugarParameter("@Id0",1) + }, "whereSingle2"); + } + private void whereSingle3() + { + Expression> exp = it => it.Id > 1 || it.Name == "a"; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " (( [Id] > @Id0 ) OR ( [Name] = @Name1 ))", new List() { + new SugarParameter("@Id0",1), + new SugarParameter("@Name1","a") + }, "whereSingle3"); + } + private void whereSingle4() + { + Expression> exp = it => (it.Id > 1 && it.Name != "a") || it.Name == "a1"; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ((( [Id] > @Id0 ) AND ( [Name] <> @Name1 )) OR ( [Name] = @Name2 )) ", new List() { + new SugarParameter("@Id0",1), + new SugarParameter("@Name1","a"), + new SugarParameter("@Name2","a1") + }, "whereSingle4"); + } + private void whereSingle5() + { + string name = "a"; + WhereConst.name = "a1"; + Expression> exp = it => (it.Id > 1 && it.Name != name) || it.Name == WhereConst.name; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ((( [Id] > @Id0 ) AND ( [Name] <> @Name1 )) OR ( [Name] = @Name2 )) ", new List() { + new SugarParameter("@Id0",1), + new SugarParameter("@Name1","a"), + new SugarParameter("@Name2","a1") + }, "whereSingle5"); + } + private void whereSingle6() + { + string name = "a"; + WhereConst.name = "a1"; + Expression> exp = it => (it.Id > 1 && it.Name != name||it.Id==1) || it.Name == WhereConst.name; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " (((( [Id] > @Id0 ) AND ( [Name] <> @Name1 )) OR ( [Id] = @Id2 )) OR ( [Name] = @Name3 ))", new List() { + new SugarParameter("@Id0",1), + new SugarParameter("@Name1","a"), + new SugarParameter("@Id2",1), + new SugarParameter("@Name3","a1") + }, "whereSingle6"); + } + private void whereSingle7(Student st) + { + Expression> exp = it => it.Id > st.Id; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Id] > @Id0 )", new List() { + new SugarParameter("@Id0",1) + }, "whereSingle7"); + } + + private void whereSingle8(Student st) + { + Expression> exp = it => it.Name == null; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Name] IS NULL )", new List() { + + }, "whereSingle8"); + } + + private void whereSingle9(Student st) + { + Expression> exp = it => it.Name == st.Name; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Name] = @Name0 )", new List() + { + new SugarParameter("@Name0",null) + }, "whereSingle9"); + } + + + private void whereSingle10() + { + Expression> exp = it => true; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( 1 = 1 )", new List() + { + + }, "whereSingle10"); + } + + + private void whereSingle11() + { + Expression> exp = it => !true; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( 1 = 2 )", new List() + { + + }, "whereSingle11"); + } + + private void whereSingle12() + { + Expression> exp = it => it.Bool1==true; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Bool1] = @Bool10 )", new List() + { + new SugarParameter("@Bool10",true) + }, "whereSingle12"); + } + + private void whereSingle13() + { + Expression> exp = it => it.Name!=null; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Name] IS NOT NULL )", new List() + { + + }, "whereSingle13"); + } + + private void whereSingle14() + { + Expression> exp = it =>true&& it.Name != null; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( 1 = 1 ) AND( [Name] IS NOT NULL ))", new List() + { + + }, "whereSingle14"); + } + + private void whereSingle15() + { + Expression> exp = it =>it.Money2 == 1; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Money2] = @Const0 )", new List() + { + new SugarParameter("@Const0",1) + }, "whereSingle15"); + } + + private void whereSingle16() + { + Dictionary dic = new Dictionary(); + dic.Add("key", "x1"); + Expression> exp = it => it.String == dic["key"]; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [String] = @Const0 )", new List() + { + new SugarParameter("@Const0",dic["key"]) + }, "whereSingle16"); + } + + private void whereSingle17() + { + Expression> exp = it =>true&&it.String.Contains("a"); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( 1 = 1 ) AND ([String] like '%'+@MethodConst1+'%') )", new List() + { + new SugarParameter("@MethodConst1","a") + }, "whereSingle17"); + } + + private void whereSingle18() + { + Expression> exp = it => !it.Bool1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "NOT ( [Bool1]=1 ) ", new List() + { + + }, "whereSingle18"); + } + private void whereSingle19() + { + Expression> exp = it => it.Bool2.Value==false; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Bool2] = @Value0 )", new List() + { + new SugarParameter("@Value0",false) + }, "whereSingle19"); + } + private void whereSingle20() + { + Expression> exp = it => it.Bool2.Value == it.Bool1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Bool2] = [Bool1] )", new List() + { + + }, "whereSingle19"); + } + + private void whereSingle21() + { + Expression> exp = it => it.Bool2.Value; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Bool2]=1 )", new List() + { + + }, "whereSingle21"); + } + + private void whereSingle22() + { + Expression> exp = it => !it.Bool2.Value; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "NOT ( [Bool2]=1 ) ", new List() + { + + }, "whereSingle22"); + } + + private void whereSingle23() + { + decimal? val = 1; + Expression> exp = it => it.Decimal2==val.Value; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Decimal2] = @Const0 )", new List() + { + new SugarParameter("@Const0",val) + }, "whereSingle23"); + } + } + + public class WhereConst + { + public static string name { get; set; } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Insert.cs b/Src/Asp.Net/OracleTest/UnitTest/Insert.cs new file mode 100644 index 000000000..ecd4ccb8a --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Insert.cs @@ -0,0 +1,152 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class Insert : UnitTestBase + { + private Insert() { } + public Insert(int eachCount) + { + this.Count = eachCount; + } + + public void Init() + { + var db = GetInstance(); + var insertObj = new Student() { Name = "jack", CreateTime = Convert.ToDateTime("2010-1-1"), SchoolId=0 }; + db.IgnoreColumns.Add("TestId", "Student"); + //db.MappingColumns.Add("id","dbid", "Student"); + + var t1 = db.Insertable(insertObj).ToSql(); + base.Check(@"INSERT INTO [STudent] + ([SchoolId],[Name],[CreateTime]) + VALUES + (@SchoolId,@Name,@CreateTime) ;SELECT SCOPE_IDENTITY();", + new List() { + new SugarParameter("@SchoolId",0), + new SugarParameter("@CreateTime",Convert.ToDateTime("2010-1-1")), + new SugarParameter("@Name","jack") + }, t1.Key, t1.Value, "Insert t1 error" + ); + + + //Insert reutrn Command Count + var t2 = db.Insertable(insertObj).ExecuteCommand(); + + db.IgnoreColumns = null; + //Only insert Name + var t3 = db.Insertable(insertObj).InsertColumns(it => new { it.Name }).ToSql(); + base.Check(@"INSERT INTO [STudent] + ([Name]) + VALUES + (@Name) ;SELECT SCOPE_IDENTITY();", new List() { + new SugarParameter("@Name","jack") + }, t3.Key, t3.Value, "Insert t3 error"); + + + //Ignore Name and TestId + var t4 = db.Insertable(insertObj).IgnoreColumns(it => new { it.Name, it.TestId }).ToSql(); + base.Check(@"INSERT INTO [STudent] + ([SchoolId],[CreateTime]) + VALUES + (@SchoolId,@CreateTime) ;SELECT SCOPE_IDENTITY();", + new List() { + new SugarParameter("@SchoolId",0), + new SugarParameter("@CreateTime",Convert.ToDateTime("2010-1-1")), + }, t4.Key, t4.Value, "Insert t4 error" + ); + + //Ignore Name and TestId + var t5 = db.Insertable(insertObj).IgnoreColumns(it => it == "Name" || it == "TestId").With(SqlWith.UpdLock).ToSql(); + base.Check(@"INSERT INTO [STudent] WITH(UPDLOCK) + ([SchoolId],[CreateTime]) + VALUES + (@SchoolId,@CreateTime) ;SELECT SCOPE_IDENTITY();", +new List() { + new SugarParameter("@SchoolId",0), + new SugarParameter("@CreateTime",Convert.ToDateTime("2010-1-1")), +}, t5.Key, t5.Value, "Insert t5 error" +); + //Use Lock + var t6 = db.Insertable(insertObj).With(SqlWith.UpdLock).ToSql(); + base.Check(@"INSERT INTO [STudent] WITH(UPDLOCK) + ([SchoolId],[Name],[CreateTime]) + VALUES + (@SchoolId,@Name,@CreateTime) ;SELECT SCOPE_IDENTITY();", +new List() { + new SugarParameter("@SchoolId",0), + new SugarParameter("@CreateTime",Convert.ToDateTime("2010-1-1")), + new SugarParameter("@Name","jack") +}, t6.Key, t6.Value, "Insert t6 error" +); + + var insertObj2 = new Student() { Name = null,SchoolId=0, CreateTime = Convert.ToDateTime("2010-1-1") }; + var t8 = db.Insertable(insertObj2).Where(true/* Is insert null */, true/*off identity*/).ToSql(); + base.Check(@"INSERT INTO [STudent] + ([ID],[SchoolId],[CreateTime]) + VALUES + (@ID,@SchoolId,@CreateTime) ;SELECT SCOPE_IDENTITY();", + new List() { + new SugarParameter("@SchoolId", 0), + new SugarParameter("@ID", 0), + new SugarParameter("@CreateTime", Convert.ToDateTime("2010-1-1")) + }, + t8.Key, + t8.Value, + "Insert t8 error" + ); + + + db.IgnoreColumns = new IgnoreColumnList(); + db.IgnoreColumns.Add("TestId", "Student"); + + //Insert List + var insertObjs = new List(); + for (int i = 0; i < 1000; i++) + { + insertObjs.Add(new Student() { Name = "name" + i }); + } + var s9 = db.Insertable(insertObjs.ToArray()).InsertColumns(it => new { it.Name }).With(SqlWith.UpdLock).ToSql(); + + insertObj.Name = null; + var t10 = db.Insertable(insertObj).ExecuteCommand(); + + var t11 = db.Insertable(new MyStudent() { Id = 1, Name = "张三" }).AS("Student").ToSql(); + base.Check(@"INSERT INTO [Student] + ([Name]) + VALUES + (@Name) ;SELECT SCOPE_IDENTITY();", new List() { + new SugarParameter("@Name","张三") + }, t11.Key, t11.Value, "Insert t11 error"); + + + var t12 = db.Insertable(new { Name = "a" }).ToSql(); + base.Check(@"INSERT INTO [STudent] + ([Name]) + VALUES + (@Name) ;SELECT SCOPE_IDENTITY();", new List() { + new SugarParameter("@Name","a") + }, t12.Key, t12.Value, "Insert t12 error"); + + var t13 = db.Insertable(new Dictionary() { {"id",0 },{ "name","2"} }).ToSql(); + base.Check(@"INSERT INTO [STudent] + ([Name]) + VALUES + (@Name) ;SELECT SCOPE_IDENTITY();", new List() { + new SugarParameter("@Name","2") + }, t13.Key, t13.Value, "Insert t13 error"); + } + } + + public class MyStudent { + + public int Id { get; set; } + public string Name { get; set; } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Mapping .cs b/Src/Asp.Net/OracleTest/UnitTest/Mapping .cs new file mode 100644 index 000000000..07730ab94 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Mapping .cs @@ -0,0 +1,69 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class Mapping : UnitTestBase + { + private Mapping() { } + public Mapping(int eachCount) + { + this.Count = eachCount; + } + + public void Init() + { + + var db = GetInstance(); + var t1 = db.Queryable().Where(it => it.Id == 1).ToSql(); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] WHERE ( [ID] = @Id0 ) ", null, t1.Key, null, "Mapping t1 error"); + + db.MappingColumns.Add("Id", "id", "School"); + var t2 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }) + .Where(st => st.Id == 1) + .Where((st, sc) => sc.Id == 1) + .Where((st, sc) => sc.Id == st.Id) + .GroupBy(st => st.Id) + .GroupBy((st, sc) => sc.Id).OrderBy(st => st.Id, OrderByType.Asc) + .Select((st, sc) => new { stid = st.Id, scid = sc.Id }).ToSql(); + base.Check(@"SELECT [st].[ID] AS [stid] , [sc].[id] AS [scid] FROM [STudent] st Left JOIN School sc ON ( [st].[SchoolId] = [sc].[id] ) WHERE ( [st].[ID] = @Id0 ) AND ( [sc].[id] = @Id1 ) AND ( [sc].[id] = [st].[ID] )GROUP BY [st].[ID],[sc].[id] ORDER BY [st].[ID] ASC ", + null, t2.Key, null, " Mapping t2 error"); + var x2 = GetInstance(); + + var q = x2.Queryable().AS("t"); + var t3 = q.ToSql(); + var t4 = q.ToSql(); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [t] ", null, t3.Key, null, "Mapping t3 error"); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [t] ", null, t4.Key, null, "Mapping t3 error"); + + var x3 = GetInstance2(); + x3.MappingTables.Add("Student", "studenT"); + int count = 0; + var t5 = x3.Queryable().ToPageList(1,2,ref count); + } + + public new SqlSugarClient GetInstance() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { InitKeyType = InitKeyType.Attribute, ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); + return db; + } + public SqlSugarClient GetInstance2() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { InitKeyType = InitKeyType.Attribute, ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); + db.Ado.IsEnableLogEvent = true; + db.Ado.LogEventStarting = (sql, pars) => + { + Console.WriteLine(sql + "\r\n" + db.RewritableMethods.SerializeObject(pars)); + Console.WriteLine(); + }; + return db; + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Query/JoinQuery.cs b/Src/Asp.Net/OracleTest/UnitTest/Query/JoinQuery.cs new file mode 100644 index 000000000..556cee8bc --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Query/JoinQuery.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using System.Linq.Expressions; +using OrmTest.Models; +namespace OrmTest.UnitTest +{ + public class JoinQuery : UnitTestBase + { + private JoinQuery() { } + public JoinQuery(int eachCount) + { + this.Count = eachCount; + } + internal void Init() + { + base.Begin(); + for (int i = 0; i < base.Count; i++) + { + Q1(); + Q2(); + Q3(); + Q4(); + q5(); + q6(); + q7(); + } + base.End("Method Test"); + } + + private void q6() + { + using (var db = GetInstance()) + { + var join6 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).Select((st, sc) => new ViewModelStudent { Name = st.Name, SchoolId = SqlFunc.AggregateMin(sc.Id) }).ToSql(); + + string sql = @"SELECT [st].[Name] AS [Name] , MIN([sc].[Id]) AS [SchoolId] FROM [STudent] st Left JOIN School sc ON ( [st].[SchoolId] = [sc].[Id] ) "; + base.Check(sql, null, join6.Key, null, "join 6 Error"); + } + } + + private void q7() + { + using (var db = GetInstance()) + { + var join7 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).Select((st, sc) => new ViewModelStudent { Name = st.Name, SchoolId = SqlFunc.AggregateMin(sc.Id*1) }).ToSql(); + + string sql = @"SELECT [st].[Name] AS [Name] , MIN(( [sc].[Id] * @Id0 )) AS [SchoolId] FROM [STudent] st Left JOIN School sc ON ( [st].[SchoolId] = [sc].[Id] ) "; + base.Check(sql, new List() { + new SugarParameter("@Id0",1) + }, join7.Key, join7.Value, "join 7 Error"); + } + } + + private void q5() + { + using (var db = GetInstance()) + { + db.MappingTables.Add("School", "SchoolTable"); + var join5= db.Queryable((st, sc) => st.SchoolId == sc.Id).Select(st => st) + .GroupBy(st=> new{ st.Id,st.Name }) + .ToSql(); + string sql = @"SELECT st.* FROM [STudent] st ,[SchoolTable] sc WHERE ( [st].[SchoolId] = [sc].[Id] )GROUP BY [st].[ID],[st].[Name] "; + base.Check(sql, null, join5.Key, null, "join 5 Error"); + } + } + + private void Q4() + { + using (var db = GetInstance()) + { + db.MappingTables.Add("School", "SchoolTable"); + var join4 = db.Queryable((st, sc) => st.SchoolId == sc.Id).Select(st=>st).ToSql(); + string sql = @"SELECT st.* FROM [STudent] st ,[SchoolTable] sc WHERE ( [st].[SchoolId] = [sc].[Id] ) "; + base.Check(sql, null, join4.Key, null, "join 4 Error"); + } + } + + + private void Q3() + { + using (var db = GetInstance()) + { + var join3 = db.Queryable("Student", "st") + .AddJoinInfo("School", "sh", "sh.id=st.schoolid") + .Where("st.id>@id") + .AddParameters(new { id = 1 }) + .Select("st.*").ToSql(); + string sql = @"SELECT st.* FROM [Student] st Left JOIN School sh ON sh.id=st.schoolid WHERE st.id>@id "; + base.Check(sql,new List() {new SugarParameter("@id",1)}, join3.Key, join3.Value, "join 3 Error"); + } + } + + public void Q1() + { + using (var db = GetInstance()) + { + var join1 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).Where(st => st.Id > 0).Select("*").ToSql(); + base.Check(@"SELECT * FROM [STudent] st Left JOIN School sc ON ( [st].[SchoolId] = [sc].[Id] ) WHERE ( [st].[ID] > @Id0 ) ", + new List() { + new SugarParameter("@Id0",0) + }, join1.Key, join1.Value, "join 1 Error"); + } + } + public void Q2() + { + using (var db = GetInstance()) + { + var join2 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).Where(st => st.Id > 2).Select("*").ToSql(); + base.Check(@"SELECT * FROM [STudent] st Left JOIN School sc ON ( [st].[SchoolId] = [sc].[Id] ) WHERE ( [st].[ID] > @Id0 ) ", + new List() { + new SugarParameter("@Id0",2) + }, join2.Key, join2.Value, "join 2 Error"); + } + } + + + public new SqlSugarClient GetInstance() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer }); + db.Ado.IsEnableLogEvent = true; + db.Ado.LogEventStarting = (sql, pars) => + { + Console.WriteLine(sql + " " + pars); + }; + return db; + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Query/SelectQuery.cs b/Src/Asp.Net/OracleTest/UnitTest/Query/SelectQuery.cs new file mode 100644 index 000000000..d3d8f4fe0 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Query/SelectQuery.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using System.Linq.Expressions; +using OrmTest.Models; +namespace OrmTest.UnitTest +{ + public class SelectQuery : UnitTestBase + { + private SelectQuery() { } + public SelectQuery(int eachCount) + { + this.Count = eachCount; + } + internal void Init() + { + base.Begin(); + for (int i = 0; i < base.Count; i++) + { + Q2(); + } + base.End("Method Test"); + } + + public void Q2() + { + using (var db = GetInstance()) + { + //db.Database.IsEnableLogEvent = true; + db.Ado.LogEventStarting = (sql, pars) => + { + Console.WriteLine(sql + " " + pars); + }; + + + #region dr ot entity + db.IgnoreColumns.Add("TestId", "Student"); + var s1 = db.Queryable().Select(it => new ViewModelStudent2 { Name = it.Name, Student = it }).ToList(); + var s2 = db.Queryable().Select(it => new { id = it.Id, w = new { x = it } }).ToList(); + var s3 = db.Queryable().Select(it => new { newid = it.Id }).ToList(); + var s4 = db.Queryable().Select(it => new { newid = it.Id, obj = it }).ToList(); + var s5 = db.Queryable().Select(it => new ViewModelStudent2 { Student = it, Name = it.Name }).ToList(); + #endregion + + + #region sql and parameters validate + var t1 = db.Queryable((st, sc) => new object[] { + JoinType.Inner,st.Id==sc.Id + }).GroupBy(st => st.Id).Having(st => SqlFunc.AggregateAvg(st.Id) == 1).Select(st => new { avgId = SqlFunc.AggregateAvg(st.Id) }).ToSql(); + base.Check("SELECT AVG([st].[ID]) AS [avgId] FROM [STudent] st Inner JOIN School sc ON ( [st].[ID] = [sc].[Id] ) GROUP BY [st].[ID] HAVING (AVG([st].[ID]) = @Const0 ) ", + new List() { + new SugarParameter("@Const0",1) + } + , + t1.Key, t1.Value, " select t1 Error"); + + + var t2 = db.Queryable((st, st2) => new object[] { + JoinType.Left,st.Id==st2.Id + }) + .Where(st => st.Id > 0) + .Select((st, st2) => new { stid = st.Id, scId = st2.Id, xx = st }).ToSql(); + + base.Check("SELECT [st].[Id] AS [stid] , [st2].[Id] AS [scId] , [st].[Id] AS [School.Id] , [st].[Name] AS [School.Name] FROM [School] st Left JOIN School st2 ON ( [st].[Id] = [st2].[Id] ) WHERE ( [st].[Id] > @Id0 ) " + , new List() { + new SugarParameter("@Id0",0) + }, t2.Key, t2.Value, "select t2 Error"); + + + var t3 = db.Queryable((st, sc, sc2) => new object[] { + JoinType.Left,st.SchoolId==sc.Id, + JoinType.Left,sc2.Id==sc.Id + }).Where(st => st.Id > 0) + .Select((st) => new School() { Id = st.Id }).ToSql(); + base.Check("SELECT [st].[ID] AS [Id] FROM [STudent] st Left JOIN School sc ON ( [st].[SchoolId] = [sc].[Id] ) Left JOIN School sc2 ON ( [sc2].[Id] = [sc].[Id] ) WHERE ( [st].[ID] > @Id0 ) ", + new List() { + new SugarParameter("@Id0",0) + }, t3.Key, t3.Value, "select t3 Error"); + #endregion + + + } + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Query/SingleQuery.cs b/Src/Asp.Net/OracleTest/UnitTest/Query/SingleQuery.cs new file mode 100644 index 000000000..4afbc8c4d --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Query/SingleQuery.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using System.Linq.Expressions; +using OrmTest.Models; +namespace OrmTest.UnitTest +{ + public class SingleQuery : UnitTestBase + { + private SingleQuery() { } + public SingleQuery(int eachCount) + { + this.Count = eachCount; + } + internal void Init() + { + base.Begin(); + for (int i = 0; i < base.Count; i++) + { + Q2(); + } + base.End("Method Test"); + } + + public void Q2() + { + using (var db = GetInstance()) + { + var t1 = db.Queryable().ToSql(); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent]", null, t1.Key, null, "single t1 Error"); + + var t2 = db.Queryable().With(SqlWith.NoLock).ToSql(); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] WITH(NOLOCK)", null, t2.Key, null, "single t2 Error"); + + var t3 = db.Queryable().OrderBy(it=>it.Id).ToSql(); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] ORDER BY [ID] ASC", null, t3.Key, null, "single t3 Error"); + + var t4 = db.Queryable().OrderBy(it => it.Id).Take(3).ToSql(); + base.Check(@"SELECT * FROM (SELECT [ID],[SchoolId],[Name],[CreateTime],ROW_NUMBER() OVER(ORDER BY [ID] ASC) AS RowIndex FROM [STudent] ) T WHERE RowIndex BETWEEN 1 AND 3", null, t4.Key, null, "single t4 Error"); + + var t5 = db.Queryable().OrderBy(it => it.Id).Skip(3).ToSql(); + base.Check(@"SELECT * FROM (SELECT [ID],[SchoolId],[Name],[CreateTime],ROW_NUMBER() OVER(ORDER BY [ID] ASC) AS RowIndex FROM [STudent] ) T WHERE RowIndex BETWEEN 4 AND 9223372036854775807", null, t5.Key,null, "single t5 Error"); + + int pageIndex = 2; + int pageSize = 10; + var t6 = db.Queryable().OrderBy(it => it.Id,OrderByType.Desc).Skip((pageIndex-1)*pageSize).Take(pageSize).ToSql(); + base.Check(@"SELECT * FROM (SELECT [ID],[SchoolId],[Name],[CreateTime],ROW_NUMBER() OVER(ORDER BY [ID] DESC) AS RowIndex FROM [STudent] ) T WHERE RowIndex BETWEEN 11 AND 20", null, t6.Key, null, "single t6 Error"); + + + int studentCount=db.Ado.GetInt("select count(1) from Student"); + var countIsSuccess=db.Queryable().Count()== studentCount; + if (!countIsSuccess) { + throw new Exception(" single countIsSuccess Error"); + } + + var t7 = db.Queryable().OrderBy(it => it.Id, OrderByType.Desc).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToPageList(pageIndex,pageSize,ref studentCount); + countIsSuccess = studentCount == db.Queryable().OrderBy(it => it.Id, OrderByType.Desc).Skip((pageIndex - 1) * pageSize).Take(pageSize * pageIndex).Count(); + if (!countIsSuccess) + { + throw new Exception("single t7 Error"); + } + + int studentMin = db.Ado.GetInt("select min(id) from Student"); + var minIsSuccess = db.Queryable().Min(it=>it.Id) == studentMin; + if (!minIsSuccess) + { + throw new Exception("single minIsSuccess Error"); + } + + int studentMax = db.Ado.GetInt("select max(id) from Student"); + var maxIsSuccess = db.Queryable().Max(it => it.Id) == studentMax; + if (!maxIsSuccess) + { + throw new Exception("single maxIsSuccess Error"); + } + + int studentAvg = db.Ado.GetInt("select avg(id) from Student"); + var avgIsSuccess = db.Queryable().Avg(it => it.Id) == studentAvg; + if (!maxIsSuccess) + { + throw new Exception(" single avgIsSuccess Error"); + } + + int studentSum = db.Ado.GetInt("select sum(id) from Student"); + var sumIsSuccess = db.Queryable().Sum(it => it.Id) == studentSum; + if (!sumIsSuccess) + { + throw new Exception("single sumIsSuccess Error"); + } + + var t8 = db.Queryable() + .Where(it=>it.Id==1) + .WhereIF(true,it=> SqlFunc.Contains(it.Name,"a")) + .OrderBy(it => it.Id, OrderByType.Desc).Skip((pageIndex - 1) * pageSize).Take(pageSize ).With(SqlWith.NoLock).ToSql(); + base.Check(@"SELECT * FROM (SELECT [ID],[SchoolId],[Name],[CreateTime],ROW_NUMBER() OVER(ORDER BY [ID] DESC) AS RowIndex FROM [STudent] WITH(NOLOCK) WHERE ( [ID] = @Id0 ) AND ([Name] like '%'+@MethodConst1+'%') ) T WHERE RowIndex BETWEEN 11 AND 20", new List() { + new SugarParameter("@Id0",1),new SugarParameter("@MethodConst1","a") + }, t8.Key, t8.Value,"single t8 Error"); + + + + var t9 = db.Queryable() + .In(1) + .Select(it => new { it.Id, it.Name,x=it.Id }).ToSql(); + base.Check("SELECT [ID] AS [Id] , [Name] AS [Name] , [ID] AS [x] FROM [STudent] WHERE [Id] IN (@InPara0) ", new List() { + new SugarParameter("@InPara0",1) },t9.Key,t9.Value, "single t9 error"); + + var t10 = db.Queryable().Select(it => new StudentEnum() { Id = SqlFunc.GetSelfAndAutoFill(it.Id) }).ToSql(); + base.Check("SELECT * FROM [STudent] ", null, t10.Key, t10.Value, "single t10 error"); + + var t11= db.Queryable().GroupBy("id").OrderBy("id").Select("id").ToSql(); + base.Check("SELECT id FROM [STudent] GROUP BY id ORDER BY id ", null, t11.Key, t11.Value, "single t11 error"); + } + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Setting/Attribute.cs b/Src/Asp.Net/OracleTest/UnitTest/Setting/Attribute.cs new file mode 100644 index 000000000..e0e8da931 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Setting/Attribute.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class Attribute : UnitTestBase + { + public Attribute(int eachCount) + { + this.Count = eachCount; + } + public void Init() + { + + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Setting/AutoClose.cs b/Src/Asp.Net/OracleTest/UnitTest/Setting/AutoClose.cs new file mode 100644 index 000000000..338a29184 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Setting/AutoClose.cs @@ -0,0 +1,27 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class AutoClose : UnitTestBase + { + public AutoClose(int eachCount) + { + this.Count = eachCount; + } + public void Init() + { + //IsAutoCloseConnection + for (int i = 0; i < this.Count; i++) + { + var db = GetInstance(); + var x = db.Queryable().ToList(); + } + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Setting/MapColumn.cs b/Src/Asp.Net/OracleTest/UnitTest/Setting/MapColumn.cs new file mode 100644 index 000000000..341a5e3b4 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Setting/MapColumn.cs @@ -0,0 +1,14 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class MapColumn : UnitTestBase + { + + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/Setting/MapTable.cs b/Src/Asp.Net/OracleTest/UnitTest/Setting/MapTable.cs new file mode 100644 index 000000000..84d35bc48 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Setting/MapTable.cs @@ -0,0 +1,23 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class MapTable : UnitTestBase + { + public void Init() + { + //IsAutoCloseConnection + for (int i = 0; i < 200; i++) + { + var db = GetInstance(); + var x = db.Queryable().ToList(); + } + } + } +} diff --git a/Src/Asp.Net/OracleTest/UnitTest/UnitTestBase.cs b/Src/Asp.Net/OracleTest/UnitTest/UnitTestBase.cs new file mode 100644 index 000000000..1aeea8b30 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/UnitTestBase.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using SqlSugar; +using System.Linq; +namespace OrmTest.UnitTest +{ + public class UnitTestBase + { + public int Count { get; set; } + private DateTime BeginTime { get; set; } + private DateTime EndTime { get; set; } + + public void Begin() + { + this.BeginTime = DateTime.Now; + } + + public void End(string title) + { + this.EndTime = DateTime.Now; + Console.WriteLine(title + " \r\nCount: " + this.Count + "\r\nTime: " + (this.EndTime - this.BeginTime).TotalSeconds + " Seconds \r\n"); + } + + internal void Check(string value, List pars, string validValue, List validPars, string errorMessage) + { + if (value.Trim() != validValue.Trim()) + { + throw new Exception(errorMessage); + } + if (pars != null && pars.Count > 0) + { + if (pars.Count != validPars.Count) + { + throw new Exception(errorMessage); + } + else + { + foreach (var item in pars) + { + if (!validPars.Any(it => it.ParameterName.Equals(item.ParameterName) && it.Value.ObjToString().Equals(item.Value.ObjToString()))) + { + throw new Exception(errorMessage); + } + } + } + } + } + + public SqlSugarClient GetInstance() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); + return db; + } + } +} \ No newline at end of file diff --git a/Src/Asp.Net/OracleTest/UnitTest/Update.cs b/Src/Asp.Net/OracleTest/UnitTest/Update.cs new file mode 100644 index 000000000..bde5ffe24 --- /dev/null +++ b/Src/Asp.Net/OracleTest/UnitTest/Update.cs @@ -0,0 +1,165 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OrmTest.UnitTest +{ + public class Update : UnitTestBase + { + private Update() { } + public Update(int eachCount) + { + this.Count = eachCount; + } + + public void Init() + { + var db = GetInstance(); + var updateObj = new Student() { Id = 1, Name = "jack",SchoolId=0, CreateTime = Convert.ToDateTime("2017-05-21 09:56:12.610") }; + var updateObjs = new List() { updateObj,new Student() { Id=2,Name="sun",SchoolId=0 } }.ToArray(); + db.IgnoreColumns.Add("TestId", "Student"); + //db.MappingColumns.Add("id","dbid", "Student"); + + var t1 = db.Updateable(updateObj).ToSql(); + base.Check(@"UPDATE [STudent] SET + [SchoolId]=@SchoolId,[Name]=@Name,[CreateTime]=@CreateTime WHERE [Id]=@Id", new List() { + new SugarParameter("@SchoolId",0), + new SugarParameter("@ID",1), + new SugarParameter("@CreateTime", Convert.ToDateTime("2017-05-21 09:56:12.610")), + new SugarParameter("@Name", "jack") + }, t1.Key, t1.Value,"Update t1 error"); + + //update reutrn Command Count + var t2 = db.Updateable(updateObj).ExecuteCommand(); + + db.IgnoreColumns = null; + //Only update Name + var t3 = db.Updateable(updateObj).UpdateColumns(it => new { it.Name }).ToSql(); + base.Check(@"UPDATE [STudent] SET + [Name]=@Name WHERE [Id]=@Id", new List() { + new SugarParameter("@ID",1), + new SugarParameter("@Name", "jack") + }, t3.Key, t3.Value, "Update t3 error"); + + //Ignore Name and TestId + var t4 = db.Updateable(updateObj).IgnoreColumns(it => new { it.Name, it.TestId }).ToSql(); + base.Check(@"UPDATE [STudent] SET + [SchoolId]=@SchoolId,[CreateTime]=@CreateTime WHERE [Id]=@Id", new List() { + new SugarParameter("@CreateTime",Convert.ToDateTime("2017-05-21 09:56:12.610")), + new SugarParameter("@SchoolId", 0), + new SugarParameter("@ID",1), + }, t4.Key, t4.Value, "Update t4 error"); + + //Ignore Name and TestId + var t5 = db.Updateable(updateObj).IgnoreColumns(it => it == "Name" || it == "TestId").With(SqlWith.UpdLock).ToSql(); + base.Check(@"UPDATE [STudent] WITH(UPDLOCK) SET + [SchoolId]=@SchoolId,[CreateTime]=@CreateTime WHERE [Id]=@Id", new List() { + new SugarParameter("@CreateTime",Convert.ToDateTime("2017-05-21 09:56:12.610")), + new SugarParameter("@SchoolId", 0), + new SugarParameter("@ID",1), + }, t5.Key, t5.Value, "Update t5 error"); + + + //Use Lock + var t6 = db.Updateable(updateObj).With(SqlWith.UpdLock).ToSql(); + base.Check(@"UPDATE [STudent] WITH(UPDLOCK) SET + [SchoolId]=@SchoolId,[Name]=@Name,[CreateTime]=@CreateTime WHERE [Id]=@Id", new List() { + new SugarParameter("@SchoolId",0), + new SugarParameter("@ID",1), + new SugarParameter("@CreateTime", Convert.ToDateTime("2017-05-21 09:56:12.610")), + new SugarParameter("@Name", "jack") + }, t6.Key, t6.Value, "Update t6 error"); + + +// //update List +// var t7 = db.Updateable(updateObjs).With(SqlWith.UpdLock).ToSql(); +// base.Check(@"UPDATE S SET S.[SchoolId]=T.[SchoolId],S.[Name]=T.[Name],S.[CreateTime]=T.[CreateTime] FROM [STudent] S WITH(UPDLOCK) INNER JOIN ( + +// SELECT N'1' AS ID,N'0' AS SchoolId,N'jack' AS Name,'2017-05-21 09:56:12.610' AS CreateTime +//UNION ALL +// SELECT N'2' AS ID,N'0' AS SchoolId,N'sun' AS Name,NULL AS CreateTime + + +// ) T ON S.[Id]=T.[Id] +// ; ", null, t7.Key, null,"Update t7 error"); + + //Re Set Value + var t8 = db.Updateable(updateObj) + .ReSetValue(it=>it.Name==(it.Name+1)).ToSql(); + base.Check(@"UPDATE [STudent] SET + [SchoolId]=@SchoolId, [Name] =( [Name] + @Const0 ),[CreateTime]=@CreateTime WHERE [Id]=@Id", + new List() { + new SugarParameter("@SchoolId",0), + new SugarParameter("@ID",1), + new SugarParameter("@CreateTime", Convert.ToDateTime("2017-05-21 09:56:12.610")), + new SugarParameter("@Const0", 1) + }, t8.Key, t8.Value, "Update t8 error" + ); + + //Where By Expression + var t9 = db.Updateable(updateObj) + .Where(it => it.Id==1).ToSql(); + base.Check(@"UPDATE [STudent] SET + [SchoolId]=@SchoolId,[Name]=@Name,[CreateTime]=@CreateTime WHERE ( [ID] = @Id0 )", + new List() { + new SugarParameter("@SchoolId",0), + new SugarParameter("@ID",1), + new SugarParameter("@Id0",1), + new SugarParameter("@CreateTime", Convert.ToDateTime("2017-05-21 09:56:12.610")), + new SugarParameter("@Name", "jack") },t9.Key,t9.Value,"Upate t9 error" + ); + updateObj.SchoolId = 18; + string name = "x"; + var t10 = db.Updateable().UpdateColumns(it => new Student() { Name =name, SchoolId=updateObj.SchoolId }).Where(it=>it.Id==11).ToSql(); + base.Check(@"UPDATE [STudent] SET + [SchoolId] = @Const0 , [Name] = @const3 WHERE ( [ID] = @Id1 )", new List() { + new SugarParameter("@const3","x"), + new SugarParameter("@Const0",18), + new SugarParameter("@Id1",11)}, + t10.Key, + t10.Value, + "Update 10 error" + ); + var t11 = db.Updateable().UpdateColumns(it => new DataTestInfo() { Datetime1=DateTime.MaxValue }).Where(it => it.Int1 == 11).ToSql(); + base.Check(@"UPDATE [DataTestInfo] SET + [Datetime1] = @constant0 WHERE ( [Int1] = @Int11 )", new List() { + new SugarParameter("@Int11",11), + new SugarParameter("@constant0",DateTime.MaxValue) }, + t11.Key, + t11.Value, + "Update 11 error" + ); + + var t12 = db.Updateable().UpdateColumns(it => new DataTestInfo() { Int2 = it.Int2+1 }).Where(it => it.Int1 == 11).ToSql(); + base.Check(@"UPDATE [DataTestInfo] SET + [Int2] = ( [Int2] + @Const0 ) WHERE ( [Int1] = @Int11 )", new List() { + new SugarParameter("@Int11",11), + new SugarParameter("@Const0",1) }, + t12.Key, + t12.Value, + "Update 12 error" + ); + + + + var t13 = db.Updateable(new { Name = "a", id=1 }).ToSql(); + base.Check(@"UPDATE [STudent] SET + [Name]=@Name WHERE [Id]=@Id", new List() { + new SugarParameter("@Name","a"), + new SugarParameter("@ID",1) + }, t13.Key, t13.Value, "Insert t13 error"); + + var t14 = db.Updateable(new Dictionary() { { "id", 0 }, { "name", "2" } }).ToSql(); + base.Check(@"UPDATE [STudent] SET + [Name]=@Name WHERE [Id]=@Id", new List() { + new SugarParameter("@Name", "2"), + new SugarParameter("@ID", 0) + }, t14.Key, t14.Value, "Insert t14 error"); + } + + } +} diff --git a/Src/Asp.Net/SqlSugar.sln b/Src/Asp.Net/SqlSugar.sln index 858aeab9e..e68eff82b 100644 --- a/Src/Asp.Net/SqlSugar.sln +++ b/Src/Asp.Net/SqlSugar.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySqlTest", "MySqlTest\MySq EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqliteTest", "SqliteTest\SqliteTest.csproj", "{D48622B3-F4CD-45CD-B1C9-868083037ECD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OracleTest", "OracleTest\OracleTest.csproj", "{4177D054-D113-4F8A-9E01-642E072F9C87}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +35,10 @@ Global {D48622B3-F4CD-45CD-B1C9-868083037ECD}.Debug|Any CPU.Build.0 = Debug|Any CPU {D48622B3-F4CD-45CD-B1C9-868083037ECD}.Release|Any CPU.ActiveCfg = Release|Any CPU {D48622B3-F4CD-45CD-B1C9-868083037ECD}.Release|Any CPU.Build.0 = Release|Any CPU + {4177D054-D113-4F8A-9E01-642E072F9C87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4177D054-D113-4F8A-9E01-642E072F9C87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4177D054-D113-4F8A-9E01-642E072F9C87}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4177D054-D113-4F8A-9E01-642E072F9C87}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE