3.2.651 版本 Where(a=>enumHashSet.Contains(a.xx)) 报错
问题描述及重现步骤:
从2.6.100升级到3.2.651后,发现以下语句会报错
public enum UserType
{
Client = 1,
Internal = 2
}
public class User
{
public UserType Type { get; set; }
}
IFreeSql fsql = new FreeSqlBuilder()
.UseConnectionString(DataType.SqlServer, connStr)
.UseGenerateCommandParameterWithLambda(true)
.Build();
var enumHashSet= new HashSet<UserType> { UserType.Client };
var sql = fsql.Select<User>().Where(a => enumHashSet.Contains(a.Type)).ToList(a => a);
//解析成
SELECT a.[Type] as1
FROM [User] a
WHERE (((a.[Type]) in System.Collections.Generic.HashSet`1[N6.Pkg.FreeSqlTestP5+UserType]))
这样了
数据库的具体版本
sql server 2008R2
安装的包
FreeSql.Provider.SqlServer 3.2.651
.net framework/. net core? 及具体版本
.net 6
收到问题,IN 不做参数化,是否合理
这个只要把HashSet改成List就行。
不过我刚看到还写了个AOP,如果将枚举 MapType 成int
fsql.Aop.ConfigEntityProperty += (s, e) =>
{
if (e.Property.PropertyType.IsEnum)
e.ModifyResult.MapType = typeof(int);
};
如果有AOP时,会有这个异常
ExpressionTree 转换类型错误,值(System.Collections.Generic.List1[SampleApp.App+UserType]),类型(System.Collections.Generic.List1[[SampleApp.App+UserType, SampleApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]),目标类型(System.Int32),Object must implement IConvertible.
https://github.com/dotnetcore/FreeSql/blob/ef42cedb6eeed94b9b63f45e251eed9d250e50a2/FreeSql/Internal/UtilsExpressionTree.cs#L2249
确实有这个问题,这个问题反复出现多个版本中,没有彻底解决。
@2881099 IEnumerable<> 是不是解析逻辑也改过了
using FreeSql;
var connStr = "...";
IFreeSql fsql = new FreeSqlBuilder()
.UseConnectionString(DataType.SqlServer, connStr)
.UseGenerateCommandParameterWithLambda(true)
.Build();
var enumerable= new []{ "小明" }.Select(a=>a);
var sql = fsql.Select<User>().Where(a => enumerable.Contains(a.Name)).ToList(a => a);
public class User
{
public string Name { get; set; } = null!;
}
报
Unhandled exception. System.Exception: Failed to convert parameter value from a SelectArrayIterator`2 to a String.
---> System.InvalidCastException: Failed to convert parameter value from a SelectArrayIterator`2 to a String.
---> System.InvalidCastException: Object must implement IConvertible.
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Microsoft.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType, Boolean& coercedToDataFeed, Boolean& typeChanged, Boolean allowStreaming)
--- End of inner exception stack trace ---
at Microsoft.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType, Boolean& coercedToDataFeed, Boolean& typeChanged, Boolean allowStreaming)
at Microsoft.Data.SqlClient.SqlParameter.GetCoercedValue()
at Microsoft.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
at Microsoft.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters, Boolean includeReturnValue)
at Microsoft.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc)
at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean isAsync, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionReques
t)
at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String method)
at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at Microsoft.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at FreeSql.Internal.CommonProvider.AdoProvider.ExecuteReaderMultiple(Int32 multipleResult, DbConnection connection, DbTransaction transaction, Action`2 fetchHandler, Action`2 schemaHandler, CommandType cmdType, String cmdText, Int32 cmdTimeout, DbParameter[] cmdParms)
--- End of inner exception stack trace ---
at FreeSql.Internal.CommonProvider.AdoProvider.LoggerException(IObjectPool`1 pool, PrepareCommandResult pc, Exception ex, DateTime dt, StringBuilder logtxt, Boolean isThrowException)
at FreeSql.Internal.CommonProvider.AdoProvider.ExecuteReaderMultiple(Int32 multipleResult, DbConnection connection, DbTransaction transaction, Action`2 fetchHandler, Action`2 schemaHandler, CommandType cmdType, String cmdText, Int32 cmdTimeout, DbParameter[] cmdParms)
at FreeSql.Internal.CommonProvider.AdoProvider.ExecuteReader(DbConnection connection, DbTransaction transaction, Action`1 fetchHandler, CommandType cmdType, String cmdText, Int32 cmdTimeout, DbParameter[] cmdParms)
at FreeSql.Internal.CommonProvider.Select0Provider`2.ToListMrPrivate[TReturn](String sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData)
at FreeSql.Internal.CommonProvider.Select0Provider`2.ToListMapReaderPrivate[TReturn](ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData)
at FreeSql.Internal.CommonProvider.Select0Provider`2.InternalToList[TReturn](Expression select)
at FreeSql.Internal.CommonProvider.Select1Provider`1.ToList[TReturn](Expression`1 select)
@tky753 v3.2.661 试下
大的逻辑没改,只是小的 bug 修复可能影响到了这个
@2881099 3.2.661试了,Enumerable还是报错,上面的没试
确实不支持.ToList下吧
var enumerable= new []{ "小明" }.Select(a=>a).ToList()
新版本已优化