From 8c72d540251c0559e04a25e7d067a2e6eeadbe84 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 21 Apr 2022 17:16:15 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20ToList=20jsonb=20?= =?UTF-8?q?=E6=98=A0=E5=B0=84=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 196 ++++++++++++------ FreeSql.DbContext/FreeSql.DbContext.xml | 9 + FreeSql/FreeSql.xml | 183 ---------------- .../CommonProvider/InsertOrUpdateProvider.cs | 2 + .../SelectProvider/Select1Provider.cs | 12 +- 5 files changed, 147 insertions(+), 255 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index aa67b813..0fc4317a 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -130,6 +130,27 @@ namespace base_entity public string ShippingAddress { get; set; } } + [Table(Name = "tb_TopicMapTypeToListDto")] + class TopicMapTypeToListDto + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + [Column(MapType = typeof(JArray))] + public List CouponIds { get; set; } + } + class TopicMapTypeToListDtoMap + { + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + public List CouponIds { get; set; } + } + static void Main(string[] args) { #region 初始化 IFreeSql @@ -144,9 +165,9 @@ namespace base_entity //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=2") - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") - //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") //.UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") @@ -172,75 +193,114 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion -// fsql.Aop.ParseExpression += (_, e) => -// { -// //解析 POCO Jsonb a.Customer.Name -// if (e.Expression is MemberExpression memExp) -// { -// var parentMemExps = new Stack(); -// parentMemExps.Push(memExp); -// while (true) -// { -// switch (memExp.Expression.NodeType) -// { -// case ExpressionType.MemberAccess: -// memExp = memExp.Expression as MemberExpression; -// if (memExp == null) return; -// parentMemExps.Push(memExp); -// break; -// case ExpressionType.Parameter: -// var tb = fsql.CodeFirst.GetTableByEntity(memExp.Expression.Type); -// if (tb == null) return; -// if (tb.ColumnsByCs.TryGetValue(parentMemExps.Pop().Member.Name, out var trycol) == false) return; -// if (new[] { typeof(JToken), typeof(JObject), typeof(JArray) }.Contains(trycol.Attribute.MapType.NullableTypeOrThis()) == false) return; -// var tmpcol = tb.ColumnsByPosition.OrderBy(a => a.Attribute.Name.Length).First(); -// var result = e.FreeParse(Expression.MakeMemberAccess(memExp.Expression, tb.Properties[tmpcol.CsName])); -// result = result.Replace(tmpcol.Attribute.Name, trycol.Attribute.Name); -// while (parentMemExps.Any()) -// { -// memExp = parentMemExps.Pop(); -// result = $"{result}->>'{memExp.Member.Name}'"; -// } -// e.Result = result; -// return; -// } -// } -// } -// }; + //fsql.UseJsonMap(); -// var methodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); -// var methodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); -// var jsonConvertSettings = JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings(); -// FreeSql.Internal.Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Customer)] = true; -// FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => -// { -// return Expression.IfThenElse( -// Expression.TypeIs(valueExp, typeof(Customer)), -// Expression.Return(returnTarget, Expression.Call(methodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(jsonConvertSettings)), typeof(object)), -// elseExp); -// }); -// FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => -// { -// if (type == typeof(Customer)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(methodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); -// return null; -// }); + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] + { + new TopicMapTypeToListDto{ + Clicks = 100, + Title = "testMapTypeTitle1", + CouponIds = new List { 1, 2, 3, 4 } + }, + new TopicMapTypeToListDto{ + Clicks = 101, + Title = "testMapTypeTitle2", + CouponIds = new List { 1, 2, 3, 1 } + }, + new TopicMapTypeToListDto{ + Clicks = 102, + Title = "testMapTypeTitle3", + CouponIds = new List { 1 } + }, + new TopicMapTypeToListDto{ + Clicks = 103, + Title = "testMapTypeTitle4", + CouponIds = new List() + }, + new TopicMapTypeToListDto{ + Clicks = 103, + Title = "testMapTypeTitle5", + }, + }).ExecuteAffrows(); + var dtomaplist2 = fsql.Select().ToList(); + var dtomaplist0 = fsql.Select().ToList(); + var dtomaplist1 = fsql.Select().ToList(a => new TopicMapTypeToListDtoMap + { + CouponIds = a.CouponIds + }); -// var seid = fsql.Insert(new SomeEntity -// { -// Customer = JsonConvert.DeserializeObject(@"{ -// ""Age"": 25, -// ""Name"": ""Joe"", -// ""Orders"": [ -// { ""OrderPrice"": 9, ""ShippingAddress"": ""Some address 1"" }, -// { ""OrderPrice"": 23, ""ShippingAddress"": ""Some address 2"" } -// ] -//}") -// }).ExecuteIdentity(); -// var selist = fsql.Select().ToList(); + #region pgsql poco + // fsql.Aop.ParseExpression += (_, e) => + // { + // //解析 POCO Jsonb a.Customer.Name + // if (e.Expression is MemberExpression memExp) + // { + // var parentMemExps = new Stack(); + // parentMemExps.Push(memExp); + // while (true) + // { + // switch (memExp.Expression.NodeType) + // { + // case ExpressionType.MemberAccess: + // memExp = memExp.Expression as MemberExpression; + // if (memExp == null) return; + // parentMemExps.Push(memExp); + // break; + // case ExpressionType.Parameter: + // var tb = fsql.CodeFirst.GetTableByEntity(memExp.Expression.Type); + // if (tb == null) return; + // if (tb.ColumnsByCs.TryGetValue(parentMemExps.Pop().Member.Name, out var trycol) == false) return; + // if (new[] { typeof(JToken), typeof(JObject), typeof(JArray) }.Contains(trycol.Attribute.MapType.NullableTypeOrThis()) == false) return; + // var tmpcol = tb.ColumnsByPosition.OrderBy(a => a.Attribute.Name.Length).First(); + // var result = e.FreeParse(Expression.MakeMemberAccess(memExp.Expression, tb.Properties[tmpcol.CsName])); + // result = result.Replace(tmpcol.Attribute.Name, trycol.Attribute.Name); + // while (parentMemExps.Any()) + // { + // memExp = parentMemExps.Pop(); + // result = $"{result}->>'{memExp.Member.Name}'"; + // } + // e.Result = result; + // return; + // } + // } + // } + // }; -// var joes = fsql.Select() -// .Where(e => e.Customer.Name == "Joe") -// .ToSql(); + // var methodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); + // var methodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); + // var jsonConvertSettings = JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings(); + // FreeSql.Internal.Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Customer)] = true; + // FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => + // { + // return Expression.IfThenElse( + // Expression.TypeIs(valueExp, typeof(Customer)), + // Expression.Return(returnTarget, Expression.Call(methodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(jsonConvertSettings)), typeof(object)), + // elseExp); + // }); + // FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => + // { + // if (type == typeof(Customer)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(methodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); + // return null; + // }); + + // var seid = fsql.Insert(new SomeEntity + // { + // Customer = JsonConvert.DeserializeObject(@"{ + // ""Age"": 25, + // ""Name"": ""Joe"", + // ""Orders"": [ + // { ""OrderPrice"": 9, ""ShippingAddress"": ""Some address 1"" }, + // { ""OrderPrice"": 23, ""ShippingAddress"": ""Some address 2"" } + // ] + //}") + // }).ExecuteIdentity(); + // var selist = fsql.Select().ToList(); + + // var joes = fsql.Select() + // .Where(e => e.Customer.Name == "Joe") + // .ToSql(); + #endregion var testitems = new[] { diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index da7ace6b..bdd16ff9 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -538,5 +538,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index be8688b0..6408f09d 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -3249,177 +3249,6 @@ - - - 测试数据库是否连接正确,本方法执行如下命令: - MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1 - Oracle: SELECT 1 FROM dual - - 命令超时设置(秒) - - true: 成功, false: 失败 - - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 查询 - - - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 在【主库】执行 - - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 在【主库】执行 - - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - - - 执行SQL返回对象集合,Query<User, Address>("select * from user where age > @age; select * from address", new { age = 25 }) - 提示:parms 参数还可以传 Dictionary<string, object> - - - - - - - - 可自定义解析表达式 @@ -4314,12 +4143,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -4395,12 +4218,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index d9e612fa..3e6b4a97 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -218,6 +218,7 @@ namespace FreeSql.Internal.CommonProvider /// public NativeTuple[], List[]> SplitSourceByIdentityValueIsNull(List source) { + if (source.Any() == false) return NativeTuple.Create(new List[0], new List[0]); if (_SplitSourceByIdentityValueIsNullFlag == 1) return NativeTuple.Create(new[] { source }, new List[0]); if (_SplitSourceByIdentityValueIsNullFlag == 2) return NativeTuple.Create(new List[0], new[] { source }); if (IdentityColumn == null) return NativeTuple.Create(LocalSplitSourceByAsTable(source), new List[0]); @@ -234,6 +235,7 @@ namespace FreeSql.Internal.CommonProvider List[] LocalSplitSourceByAsTable(List loc1) { + if (loc1.Any() == false) return new List[0]; if (_table.AsTableImpl != null) { var atarr = loc1.Select(a => new diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 5e76aa6b..18f93f0f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -255,12 +255,16 @@ namespace FreeSql.Internal.CommonProvider } return ret; } - public List ToList() => ToList(GetToListDtoSelector()); + public List ToList() => typeof(T1) == typeof(TDto) ? ToList() as List : ToList(GetToListDtoSelector()); Expression> GetToListDtoSelector() { + var expParam = _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"); + var expBinds = _tables[0].Table.Columns.Where(a => a.Value.CsType != a.Value.Attribute.MapType) + .Select(a => Expression.Bind(typeof(TDto).GetProperty(a.Value.CsName), Expression.MakeMemberAccess(expParam, _tables[0].Table.Properties[a.Value.CsName]))) + .ToArray(); return Expression.Lambda>( - typeof(TDto).InternalNewExpression(), - _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a")); + Expression.MemberInit(typeof(TDto).InternalNewExpression(), expBinds), + expParam); } public void ToChunk(Expression> select, int size, Action>> done) { @@ -1284,7 +1288,7 @@ namespace FreeSql.Internal.CommonProvider } return ret; } - public Task> ToListAsync(CancellationToken cancellationToken = default) => ToListAsync(GetToListDtoSelector(), cancellationToken); + async public Task> ToListAsync(CancellationToken cancellationToken = default) => typeof(T1) == typeof(TDto) ? await ToListAsync(false, cancellationToken) as List : await ToListAsync(GetToListDtoSelector(), cancellationToken); public Task InsertIntoAsync(string tableName, Expression> select, CancellationToken cancellationToken = default) where TTargetEntity : class => base.InternalInsertIntoAsync(tableName, select, cancellationToken);