using AME.Helpers; using FreeSql.DataAnnotations; using FreeSql.Internal; using FreeSql.Internal.CommonProvider; using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Threading; using Xunit; using static FreeSql.Tests.UnitTest1; namespace FreeSql.Tests { public class UnitTest4 { [Fact] public void WithLambdaParameter01() { using (var fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=6;TrustServerCertificate=true") .UseAutoSyncStructure(true) .UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 //, (cmd, traceLog) => Console.WriteLine(traceLog) ) .UseLazyLoading(true) .Build()) { fsql.Delete().Where("1=1").ExecuteAffrows(); var id1 = Guid.NewGuid(); var id2 = Guid.NewGuid(); var affrows = fsql.Insert(new[] { new ts_wlp01 { id = id1, status = ts_wlp01_status.completed, }, new ts_wlp01 { id = id2, status = ts_wlp01_status.pending, } }).ExecuteAffrows(); Assert.Equal(2, affrows); var items = fsql.Select().OrderBy(a => a.status).ToList(); Assert.Equal(2, items.Count); Assert.Equal(id1, items[0].id); Assert.Equal(ts_wlp01_status.completed, items[0].status); Assert.Equal(id2, items[1].id); Assert.Equal(ts_wlp01_status.pending, items[1].status); var item1Select = fsql.Select().Where(a => a.status == ts_wlp01_status.completed); var item1S0p = item1Select as Select0Provider; Assert.Single(item1S0p._params); var p0 = item1S0p._params[0]; Assert.Equal(p0.DbType, System.Data.DbType.String); Assert.Equal(p0.Value, "completed"); items = item1Select.ToList(); Assert.Single(items); Assert.Equal(id1, items[0].id); Assert.Equal(ts_wlp01_status.completed, items[0].status); var item2Select = fsql.Select().Where(a => a.status == ts_wlp01_status.pending); var item2S0p = item2Select as Select0Provider; Assert.Single(item2S0p._params); p0 = item2S0p._params[0]; Assert.Equal(p0.DbType, System.Data.DbType.String); Assert.Equal(p0.Value, "pending"); items = item2Select.ToList(); Assert.Single(items); Assert.Equal(id2, items[0].id); Assert.Equal(ts_wlp01_status.pending, items[0].status); // use var var item1status = ts_wlp01_status.completed; item1Select = fsql.Select().Where(a => a.status == item1status); item1S0p = item1Select as Select0Provider; Assert.Single(item1S0p._params); p0 = item1S0p._params[0]; Assert.Equal(p0.DbType, System.Data.DbType.String); Assert.Equal(p0.Value, "completed"); items = item1Select.ToList(); Assert.Single(items); Assert.Equal(id1, items[0].id); Assert.Equal(item1status, items[0].status); var item2status = ts_wlp01_status.pending; item2Select = fsql.Select().Where(a => a.status == item2status); item2S0p = item2Select as Select0Provider; Assert.Single(item2S0p._params); p0 = item2S0p._params[0]; Assert.Equal(p0.DbType, System.Data.DbType.String); Assert.Equal(p0.Value, "pending"); items = item2Select.ToList(); Assert.Single(items); Assert.Equal(id2, items[0].id); Assert.Equal(item2status, items[0].status); } } class ts_wlp01 { public Guid id { get; set; } [Column(MapType = typeof(string), StringLength = 20)] public ts_wlp01_status status { get; set; } } enum ts_wlp01_status { pending, completed, failed } [Fact] public void NonoLambdaParameter() { var fsql = g.sqlserver; fsql.Delete().Where("1=1").ExecuteAffrows(); var id1 = Guid.NewGuid(); var id2 = Guid.NewGuid(); var affrows = fsql.Insert(new[] { new ts_wlp02 { id = id1, status = ts_wlp02_status.completed, }, new ts_wlp02 { id = id2, status = ts_wlp02_status.pending, } }).ExecuteAffrows(); Assert.Equal(2, affrows); var items = fsql.Select().OrderBy(a => a.status).ToList(); Assert.Equal(2, items.Count); Assert.Equal(id1, items[0].id); Assert.Equal(ts_wlp02_status.completed, items[0].status); Assert.Equal(id2, items[1].id); Assert.Equal(ts_wlp02_status.pending, items[1].status); var item1Select = fsql.Select().Where(a => a.status == ts_wlp02_status.completed); Assert.Equal(@"SELECT a.[id], a.[status] FROM [ts_wlp02] a WHERE (a.[status] = N'completed')", item1Select.ToSql()); items = item1Select.ToList(); Assert.Single(items); Assert.Equal(id1, items[0].id); Assert.Equal(ts_wlp02_status.completed, items[0].status); var item2Select = fsql.Select().Where(a => a.status == ts_wlp02_status.pending); Assert.Equal(@"SELECT a.[id], a.[status] FROM [ts_wlp02] a WHERE (a.[status] = N'pending')", item2Select.ToSql()); items = item2Select.ToList(); Assert.Single(items); Assert.Equal(id2, items[0].id); Assert.Equal(ts_wlp02_status.pending, items[0].status); // use var var item1status = ts_wlp02_status.completed; item1Select = fsql.Select().Where(a => a.status == item1status); Assert.Equal(@"SELECT a.[id], a.[status] FROM [ts_wlp02] a WHERE (a.[status] = N'completed')", item1Select.ToSql()); items = item1Select.ToList(); Assert.Single(items); Assert.Equal(id1, items[0].id); Assert.Equal(item1status, items[0].status); var item2status = ts_wlp02_status.pending; item2Select = fsql.Select().Where(a => a.status == item2status); Assert.Equal(@"SELECT a.[id], a.[status] FROM [ts_wlp02] a WHERE (a.[status] = N'pending')", item2Select.ToSql()); items = item2Select.ToList(); Assert.Single(items); Assert.Equal(id2, items[0].id); Assert.Equal(item2status, items[0].status); } class ts_wlp02 { public Guid id { get; set; } [Column(MapType = typeof(string), StringLength = 20)] public ts_wlp02_status status { get; set; } } enum ts_wlp02_status { pending, completed, failed } [Fact] public void GroupSubSelect() { var fsql = g.sqlite; fsql.Delete().Where("1=1").ExecuteAffrows(); var affrows = fsql.Insert(new[]{ new ts_group_sub_select01 { code = "code_01", seqid = 1, name = "name_01" }, new ts_group_sub_select01 { code = "code_02", seqid = 2, name = "name_02" } }).ExecuteAffrows(); Assert.Equal(2, affrows); var sql = fsql.Select() .GroupBy(a => new { a.code, a.seqid, a.name }) .ToSql(g => new { g.Key.code, g.Key.seqid, g.Key.name, number = fsql.Select() .Where(o => o.seqid == 6) .Count(), number2 = 3, number3 = 5 }); Assert.Equal(@"SELECT a.""code"" as1, a.""seqid"" as2, a.""name"" as3, (SELECT count(1) FROM ""ts_group_sub_select01"" o WHERE (o.""seqid"" = 6)) as4, 3 as5, 5 as6 FROM ""ts_group_sub_select01"" a GROUP BY a.""code"", a.""seqid"", a.""name""", sql); Assert.Equal(2, fsql.Select() .GroupBy(a => new { a.code, a.seqid, a.name }) .ToList(g => new { g.Key.code, g.Key.seqid, g.Key.name, number = fsql.Select() .Where(o => o.seqid == 6) .Count(), number2 = 3, number3 = 5 }).Count); sql = fsql.Select() .GroupBy(a => new { a.code, a.seqid, a.name }) .ToSql(g => new { g.Key.code, g.Key.seqid, g.Key.name, number = fsql.Select() .Where(o => o.seqid == g.Key.seqid) .Count(), number2 = 3, number3 = 5 }); Assert.Equal(@"SELECT a.""code"" as1, a.""seqid"" as2, a.""name"" as3, (SELECT count(1) FROM ""ts_group_sub_select01"" o WHERE (o.""seqid"" = a.""seqid"")) as4, 3 as5, 5 as6 FROM ""ts_group_sub_select01"" a GROUP BY a.""code"", a.""seqid"", a.""name""", sql); Assert.Equal(2, fsql.Select() .GroupBy(a => new { a.code, a.seqid, a.name }) .ToList(g => new { g.Key.code, g.Key.seqid, g.Key.name, number = fsql.Select() .Where(o => o.seqid == g.Key.seqid) .Count(), number2 = 3, number3 = 5 }).Count); } class ts_group_sub_select01 { public Guid id { get; set; } public string code { get; set; } public int seqid { get; set; } public string name { get; set; } } [Fact] public void OneToManyLazyloading() { var fsql = g.sqlite; fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Delete().Where("1=1").ExecuteAffrows(); var repo = fsql.GetRepository(); repo.DbContextOptions.EnableCascadeSave = true; repo.Insert(new ts_otm_ll_01 { name = "001", ll_02s = new List(new[] { new ts_otm_ll_02 { title = "sub_001" }, new ts_otm_ll_02 { title = "sub_002" }, new ts_otm_ll_02 { title = "sub_003" } }) }); var item = fsql.Select().First(); Assert.NotNull(item); var childs = item.ll_02s; Assert.NotNull(childs); Assert.Equal(3, childs.Count); } public class ts_otm_ll_01 { public Guid id { get; set; } public string name { get; set; } [Navigate(nameof(ts_otm_ll_02.ll_01id))] public virtual List ll_02s { get; set; } } public class ts_otm_ll_02 { public Guid id { get; set; } public Guid ll_01id { get; set; } public string title { get; set; } } [Fact] public void SelectLambdaParameter() { using (var fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;min pool size=1;Max Pool Size=51;TrustServerCertificate=true") .UseAutoSyncStructure(true) .UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前 //, (cmd, traceLog) => Console.WriteLine(traceLog) ) .Build()) { fsql.Delete().Where("1=1").ExecuteAffrows(); var testItem = new ts_slp01(); var sql1 = fsql.Select().Where(a => a.name == testItem.GetTestName1()).ToSql(); var sql2 = fsql.Select().Where(a => a.name == testItem.GetTestName2()).ToSql(); Assert.Equal(@"SELECT a.[id], a.[name] FROM [ts_slp01] a WHERE (a.[name] = @exp_0)", sql1); Assert.Equal(@"SELECT a.[id], a.[name] FROM [ts_slp01] a WHERE (a.[name] IS NULL)", sql2); } } class ts_slp01 { public Guid id { get; set; } public string name { get; set; } public string GetTestName1() => "xxx"; public string GetTestName2() => null; } [Fact] public void SelectN_SubSelectN() { var fsql = g.sqlite; var plansql1 = fsql.Select() .LeftJoin((a, b, c, d) => a.pmcode == b.pmcode) .LeftJoin((a, b, c, d) => b.pmcode == c.pmcode && c.isdefault == 1) .InnerJoin((a, b, c, d) => c.fvcode == d.fvcode) .ToSql((a, b, c, d) => new { a.billcode, b.pmname, d.techcode }); var plansql2 = fsql.Select() .LeftJoin((a, b, c, d) => a.pmcode == b.pmcode) .LeftJoin((a, b, c, d) => b.pmcode == c.pmcode && c.isdefault == 1) .InnerJoin((a, b, c, d) => c.fvcode == d.fvcode) .ToSql((a, b, c, d) => new { a.billcode, b.pmname, d.techcode, planQty = fsql.Select() .InnerJoin((e, f) => e.code == f.pccode) .Where((e, f) => a.code == e.plancode) .Count() }); Assert.Equal(@"SELECT a.""billcode"" as1, b.""pmname"" as2, d.""techcode"" as3, (SELECT count(1) FROM ""ts_tproduct_catering"" e INNER JOIN ""ts_tproduct_catering_detail"" f ON e.""code"" = f.""pccode"" WHERE (a.""code"" = e.""plancode"")) as4 FROM ""ts_tplan"" a LEFT JOIN ""ts_tproductmode"" b ON a.""pmcode"" = b.""pmcode"" LEFT JOIN ""ts_tflowversion"" c ON b.""pmcode"" = c.""pmcode"" AND c.""isdefault"" = 1 INNER JOIN ""ts_tproflow"" d ON c.""fvcode"" = d.""fvcode""", plansql2); } class ts_tplan { public string code { get; set; } public string pmcode { get; set; } public string billcode { get; set; } } class ts_tproductmode { public string pmcode { get; set; } public string pmname { get; set; } } class ts_tflowversion { public string fvcode { get; set; } public string pmcode { get; set; } public int isdefault { get; set; } } class ts_tproflow { public string fvcode { get; set; } public string techcode { get; set; } } class ts_tproduct_catering { public string code { get; set; } public string plancode { get; set; } } class ts_tproduct_catering_detail { public string pccode { get; set; } } class ts_tmain_record { public string code { get; set; } public string barcode { get; set; } } class ts_tprocess_record { public string mrcode { get; set; } public string barcode { get; set; } public string techcode { get; set; } public int assemres { get; set; } } class ts_lawsuit { public Guid id { get; set; } public Guid lawsuit_member_id { get; set; } public Guid lawsuit_memberObligee_id { get; set; } public ts_lawsuit_member ts_lawsuit_member { get; set; } public ts_lawsuit_member ts_lawsuit_memberObligee { get; set; } } class ts_lawsuit_member { public Guid id { get; set; } public string title { get; set; } } [Fact] public void VersionByte() { var ts_lawsuititem = new ts_lawsuit { id = Guid.NewGuid(), lawsuit_memberObligee_id = Guid.NewGuid(), lawsuit_member_id = Guid.NewGuid() }; g.mysql.Insert(new[] { new ts_lawsuit_member{id = ts_lawsuititem.lawsuit_member_id, title = "ts_lawsuit_member_title"}, new ts_lawsuit_member{id = ts_lawsuititem.lawsuit_memberObligee_id, title = "ts_lawsuit_memberObligee_title"} }).ExecuteAffrows(); g.mysql.Insert(ts_lawsuititem).ExecuteAffrows(); var xxx = g.mysql.Select() .LeftJoin(a => a.ts_lawsuit_member.id == a.lawsuit_member_id) .LeftJoin(a => a.ts_lawsuit_memberObligee.id == a.lawsuit_memberObligee_id) .First(); g.sqlserver.Insert(new AppSettingII { }).ExecuteAffrows(); var item33 = g.sqlserver.Select().ToList(); var sql22 = g.sqlserver.Select() .OrderBy(a => a.ID) .Count(out var total) .Page(1, 10).ToSql(); var items22 = g.sqlserver.Select().WithSql(sql22).ToList(); var defv1 = typeof(decimal).CreateInstanceGetDefaultValue(); var defv2 = typeof(decimal?).CreateInstanceGetDefaultValue(); var fsql = g.mysql; fsql.Delete().Where("1=1").ExecuteAffrows(); var id = Guid.NewGuid(); Assert.Equal(1, fsql.Insert(new ts_ver_byte { id = id, title = "001" }).ExecuteAffrows()); var item = fsql.Select(id).First(); item.title = "002"; Assert.Equal(1, fsql.Update().SetSource(item).ExecuteAffrows()); item.title = "003"; Assert.Equal(1, fsql.Update().SetSource(item).ExecuteAffrows()); item.version = Utils.GuidToBytes(Guid.NewGuid()); item.title = "004"; Assert.Throws(() => fsql.Update().SetSource(item).ExecuteAffrows()); fsql.Delete().Where("1=1").ExecuteAffrows(); Assert.Equal(2, fsql.Insert(new[] { new ts_ver_byte { id = Guid.NewGuid(), title = "001" }, new ts_ver_byte { id = Guid.NewGuid(), title = "0011" } }).ExecuteAffrows()); var items = fsql.Select().OrderBy(a => a.title).ToList(); Assert.Equal(2, items.Count); items[0].title = "002"; items[1].title = "0022"; Assert.Equal(2, fsql.Update().SetSource(items).ExecuteAffrows()); items[0].title = "003"; items[1].title = "0033"; Assert.Equal(2, fsql.Update().SetSource(items).ExecuteAffrows()); items[0].version = Utils.GuidToBytes(Guid.NewGuid()); items[0].title = "004"; items[1].title = "0044"; Assert.Throws(() => fsql.Update().SetSource(items).ExecuteAffrows()); items[0].version = Utils.GuidToBytes(Guid.NewGuid()); items[1].version = Utils.GuidToBytes(Guid.NewGuid()); items[0].title = "004"; items[1].title = "0044"; Assert.Throws(() => fsql.Update().SetSource(items).ExecuteAffrows()); } class ts_ver_byte { public Guid id { get; set; } public string title { get; set; } [Column(IsVersion = true)] public byte[] version { get; set; } } public record ts_iif(Guid id, string title); [Fact] public void IIF() { var fsql = g.sqlserver; fsql.Delete().Where("1=1").ExecuteAffrows(); var id = Guid.NewGuid(); fsql.Insert(new ts_iif(id, "001")).ExecuteAffrows(); var item = fsql.Select().Where(a => a.id == (id != Guid.NewGuid() ? id : a.id)).First(); Assert.Equal(id, item.id); var item2 = fsql.Select().First(a => new { xxx = id != Guid.NewGuid() ? a.id : Guid.Empty }); Assert.Equal(id, item2.xxx); fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Delete().Where("1=1").ExecuteAffrows(); var typeid = Guid.NewGuid(); fsql.Insert(new ts_iif_type { id = typeid, name = "type001" }).ExecuteAffrows(); fsql.Insert(new ts_iif_topic { id = id, typeid = typeid, title = "title001" }).ExecuteAffrows(); var more1 = true; var more2 = (bool?)true; var more3 = (bool?)false; var more4 = (bool?)null; var moreitem = fsql.Select().First(a => new { a.id, a.title, a.type }); Assert.Equal(id, moreitem.id); Assert.Equal("title001", moreitem.title); Assert.Equal(typeid, moreitem.type.id); Assert.Equal("type001", moreitem.type.name); var moreitem1 = fsql.Select().First(a => new { a.id, a.title, type1 = more1 == true ? a.type : null, }); Assert.Equal(id, moreitem1.id); Assert.Equal("title001", moreitem1.title); Assert.Equal(typeid, moreitem1.type1.id); Assert.Equal("type001", moreitem1.type1.name); var moreitem2 = fsql.Select().First(a => new { a.id, a.title, type2 = more2 == true ? a.type : null, }); Assert.Equal(id, moreitem2.id); Assert.Equal("title001", moreitem2.title); Assert.Equal(typeid, moreitem2.type2.id); Assert.Equal("type001", moreitem2.type2.name); var moreitem3 = fsql.Select().First(a => new { a.id, a.title, type3 = more3 == true ? a.type : null, }); Assert.Equal(id, moreitem3.id); Assert.Equal("title001", moreitem3.title); Assert.Null(moreitem3.type3); var moreitem4 = fsql.Select().First(a => new { a.id, a.title, type4 = more4 == true ? a.type : null, }); Assert.Equal(id, moreitem4.id); Assert.Equal("title001", moreitem4.title); Assert.Null(moreitem4.type4); } class ts_iif_topic { public Guid id { get; set; } public Guid typeid { get; set; } [Navigate(nameof(typeid))] public ts_iif_type type { get; set; } public string title { get; set; } } class ts_iif_type { public Guid id { get; set; } public string name { get; set; } } public record ts_record(DateTime Date, int TemperatureC, int TemperatureF, string Summary) { public ts_record parent { get; set; } } public record ts_record_dto(DateTime Date, int TemperatureC, string Summary); [Fact] public void LeftJoinNull01() { var fsql = g.sqlite; fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Insert(new ts_record(DateTime.Now, 1, 2, "123")).ExecuteAffrows(); var fores = fsql.Select().ToList(); var fores_dtos1 = fsql.Select().ToList(); var fores_dtos2 = fsql.Select().ToList(a => new ts_record_dto(a.Date, a.TemperatureC, a.Summary)); fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Delete().Where("1=1").ExecuteAffrows(); var item = new leftjoin_null01 { name = "xx01" }; fsql.Insert(item).ExecuteAffrows(); var sel1 = fsql.Select() .LeftJoin((a, b) => a.id == b.null01_id) .First((a, b) => new { a.id, a.name, id2 = (Guid?)b.id, time2 = (DateTime?)b.time }); Assert.Null(sel1.id2); Assert.Null(sel1.time2); } class leftjoin_null01 { public Guid id { get; set; } public string name { get; set; } } class leftjoin_null02 { public Guid id { get; set; } public Guid null01_id { get; set; } public DateTime time { get; set; } } [Fact] public void TestHzyTuple() { var xxxhzytuple = g.sqlite.Select() .LeftJoin(w => w.t1.Id2 == w.t2.TemplatesId) .Where(w => w.t1.Code == "xxx" && w.t2.OptionsEntity03 == true) .OrderBy(w => w.t1.AddTime) .ToSql(); var xxxhzytupleGroupBy = g.sqlite.Select() .LeftJoin(w => w.t1.Id2 == w.t2.TemplatesId) .Where(w => w.t1.Code == "xxx" && w.t2.OptionsEntity03 == true) .GroupBy(w => new { w.t1 }) .OrderBy(w => w.Key.t1.AddTime) .ToSql(w => w.Key ); } } }