- 优化 Oracle IN :ids 值传入 IList 时报错;

This commit is contained in:
2881099 2022-08-02 13:45:05 +08:00
parent 034b4735f4
commit 66e6f39086
4 changed files with 88 additions and 75 deletions

View File

@ -753,62 +753,65 @@ namespace base_entity
}).Where(a => a.ConcurrentDictionarys.Length > 0).ToArray(); }).Where(a => a.ConcurrentDictionarys.Length > 0).ToArray();
#region pgsql poco #region pgsql poco
// fsql.Aop.ParseExpression += (_, e) => //fsql.Aop.ParseExpression += (_, e) =>
//{
// //解析 POCO Jsonb a.Customer.Name
// if (e.Expression is MemberExpression memExp)
// {
// var parentMemExps = new Stack<MemberExpression>();
// parentMemExps.Push(memExp);
// while (true)
// {
// switch (memExp.Expression.NodeType)
// { // {
// //解析 POCO Jsonb a.Customer.Name // case ExpressionType.MemberAccess:
// if (e.Expression is MemberExpression memExp) // memExp = memExp.Expression as MemberExpression;
// { // if (memExp == null) return;
// var parentMemExps = new Stack<MemberExpression>();
// parentMemExps.Push(memExp); // parentMemExps.Push(memExp);
// while (true) // 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())
// { // {
// switch (memExp.Expression.NodeType) // memExp = parentMemExps.Pop();
// { // result = $"{result}->>'{memExp.Member.Name}'";
// 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;
// }
// } // }
// } // e.Result = result;
// }; // return;
// }
// }
// }
//};
// var methodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); //void RegisterPocoType(Type pocoType)
// var methodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); //{
// var jsonConvertSettings = JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings(); // var methodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) });
// FreeSql.Internal.Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Customer)] = true; // var methodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) });
// FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => // var jsonConvertSettings = JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings();
// { // FreeSql.Internal.Utils.dicExecuteArrayRowReadClassOrTuple[pocoType] = true;
// return Expression.IfThenElse( // FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) =>
// Expression.TypeIs(valueExp, typeof(Customer)), // {
// Expression.Return(returnTarget, Expression.Call(methodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(jsonConvertSettings)), typeof(object)), // return Expression.IfThenElse(
// elseExp); // Expression.TypeIs(valueExp, pocoType),
// }); // Expression.Return(returnTarget, Expression.Call(methodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(jsonConvertSettings)), typeof(object)),
// FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => // elseExp);
// { // });
// if (type == typeof(Customer)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(methodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); // FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) =>
// return null; // {
// }); // if (type == pocoType) 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 //var seid = fsql.Insert(new SomeEntity
// { //{
// Customer = JsonConvert.DeserializeObject<Customer>(@"{ // Customer = JsonConvert.DeserializeObject<Customer>(@"{
// ""Age"": 25, // ""Age"": 25,
// ""Name"": ""Joe"", // ""Name"": ""Joe"",
// ""Orders"": [ // ""Orders"": [
@ -816,12 +819,12 @@ namespace base_entity
// { ""OrderPrice"": 23, ""ShippingAddress"": ""Some address 2"" } // { ""OrderPrice"": 23, ""ShippingAddress"": ""Some address 2"" }
// ] // ]
//}") //}")
// }).ExecuteIdentity(); //}).ExecuteIdentity();
// var selist = fsql.Select<SomeEntity>().ToList(); //var selist = fsql.Select<SomeEntity>().ToList();
// var joes = fsql.Select<SomeEntity>() //var joes = fsql.Select<SomeEntity>()
// .Where(e => e.Customer.Name == "Joe") // .Where(e => e.Customer.Name == "Joe")
// .ToSql(); // .ToSql();
#endregion #endregion
var testitems = new[] var testitems = new[]

View File

@ -733,15 +733,6 @@
<param name="modelBuilder"></param> <param name="modelBuilder"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSqlDbContextExtensions.ApplyConfigurationsFromAssembly(FreeSql.ICodeFirst,System.Reflection.Assembly,System.Func{System.Type,System.Boolean})">
<summary>
根据Assembly扫描所有继承IEntityTypeConfiguration&lt;T&gt;的配置类
</summary>
<param name="codeFirst"></param>
<param name="assembly"></param>
<param name="predicate"></param>
<returns></returns>
</member>
<member name="M:FreeSqlDbContextExtensions.CreateDbContext(IFreeSql)"> <member name="M:FreeSqlDbContextExtensions.CreateDbContext(IFreeSql)">
<summary> <summary>
创建普通数据上下文档对象 创建普通数据上下文档对象
@ -800,14 +791,5 @@
<param name="that"></param> <param name="that"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
<summary>
批量注入 Repository可以参考代码自行调整
</summary>
<param name="services"></param>
<param name="globalDataFilter"></param>
<param name="assemblies"></param>
<returns></returns>
</member>
</members> </members>
</doc> </doc>

View File

@ -1,5 +1,6 @@
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using System; using System;
using System.Collections.Generic;
using Xunit; using Xunit;
namespace FreeSql.Tests.Oracle namespace FreeSql.Tests.Oracle
@ -55,6 +56,7 @@ namespace FreeSql.Tests.Oracle
var t5 = g.oracle.Ado.Query<dynamic>("select * from \"TB_TOPIC\""); var t5 = g.oracle.Ado.Query<dynamic>("select * from \"TB_TOPIC\"");
var t6 = g.oracle.Ado.Query<xxx>("select * from TB_TOPIC where id in :ids", new { ids = new[] { 1, 2, 3 } }); var t6 = g.oracle.Ado.Query<xxx>("select * from TB_TOPIC where id in :ids", new { ids = new[] { 1, 2, 3 } });
var t7 = g.oracle.Ado.Query<xxx>("select * from TB_TOPIC where id in :ids", new { ids = new List<int>(new[] { 1, 2, 3 }) });
} }
[Fact] [Fact]

View File

@ -2,6 +2,7 @@
using FreeSql.Internal.Model; using FreeSql.Internal.Model;
using Oracle.ManagedDataAccess.Client; using Oracle.ManagedDataAccess.Client;
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Globalization; using System.Globalization;
@ -69,7 +70,32 @@ namespace FreeSql.Oracle
} }
var ret = new OracleParameter { ParameterName = $":{name}" }; var ret = new OracleParameter { ParameterName = $":{name}" };
if (dbtype != null) ret.OracleDbType = dbtype.Value; if (dbtype != null) ret.OracleDbType = dbtype.Value;
ret.Value = value; if (value is IList valueList && value is Array == false && valueList.Count > 0)
{
var valueItemType = valueList[0]?.GetType();
if (valueItemType == typeof(int)) LocalSetListValue<int>();
else if (valueItemType == typeof(long)) LocalSetListValue<long>();
else if (valueItemType == typeof(short)) LocalSetListValue<short>();
else if (valueItemType == typeof(string)) LocalSetListValue<string>();
else if(valueItemType == typeof(Guid)) LocalSetListValue<Guid>();
else if (valueItemType == typeof(char)) LocalSetListValue<char>();
else if (valueItemType == typeof(bool)) LocalSetListValue<bool>();
else if (valueItemType == typeof(uint)) LocalSetListValue<uint>();
else if (valueItemType == typeof(ulong)) LocalSetListValue<ulong>();
else if (valueItemType == typeof(ushort)) LocalSetListValue<ushort>();
else if (valueItemType == typeof(decimal)) LocalSetListValue<decimal>();
else if (valueItemType == typeof(double)) LocalSetListValue<double>();
else if (valueItemType == typeof(float)) LocalSetListValue<float>();
else if (valueItemType == typeof(DateTime)) LocalSetListValue<DateTime>();
void LocalSetListValue<T>()
{
var valueCopy = new List<T>();
foreach (var valueItem in valueList) valueCopy.Add((T)Utils.GetDataReaderValue(valueItemType, valueItem));
value = valueCopy.ToArray();
}
}
ret.Value = value; //IList 赋值会报错
return ret; return ret;
}); });