ITPub博客

首页 > 数字化转型 > 移动办公 > 预编译反射command和参数类型,以便生成更原生更快的代码

预编译反射command和参数类型,以便生成更原生更快的代码

投稿 移动办公 作者:ecclw459 时间:2026-01-26 16:53:33 0 删除 编辑

MySqlParameterCollection parameters = ((MySqlCommand)command).Parameters;    MySqlParameter t = cached.Clone();    t.Value = param.Id;     // MySqlParameter Add(MySqlParameter parameter)     return parameters.Add(t);


  • MySqlParameterCollection有两个Add方法
  • 很明显重载Add(MySqlParameter parameter)更合适
  • 调用重载Add(object value)需要做多次类型转换
  • 既然生成的代码可以控制,就需要选用更合适的重载


  • 预编译是ShadowBuilder负责,基于ADO.net(DbCommand)
  • 为了生成更原生的代码,需要知道具体的Command类型
  • 所以ShadowBuilder需要更多实际的类型信息
  • 为此本来ShadowExecutor才需要的数据源信息,现在ShadowBuilder也需要


var commandType = command.GetType(); var parametersProperty = commandType.GetProperty( "Parameters" , BindingFlags.Instance | BindingFlags.DeclaredOnly); var parametersType = parametersProperty.PropertyType; var parameterType = command.CreateParameter().GetType(); var addParameterMethod = parametersType.GetMethod( "Add" , [parameterType]);

private ICloneable _idParameter;basketballzhibo.cn [ Benchmark(Baseline = true) ] public DbParameter CreateParameter() {     var id = _command.CreateParameter();    id.ParameterName = "Id" ;    id.DbType = System.Data.DbType.Int64;    id.Value = 1L ;     return id; } [ Benchmark ] public DbParameter Clone() {     var id = (SqlParameter)_idParameter.Clone();    id.Value = 1L ;     return id; } [ GlobalSetup ] public void Setup() {     var idParameter = _command.CreateParameter();    idParameter.ParameterName = "Id" ;    idParameter.DbType = System.Data.DbType.Int64;

protected virtual DbType CheckDbTypeCore( Type valueType)    => CheckDbType(valueType); /// <summary> /// 默认数据库类型 /// </summary> /// <param name="valueType"> </param> /// <returns> </returns> public static DbType CheckDbType( Type valueType) {     if (valueType.IsArray)         return DbType.Binary;     var typeCode = Type.GetTypeCode(valueType);     return typeCode switch    {huahuaddd.com        TypeCode.Byte => DbType.Byte,        TypeCode.SByte => DbType.SByte,        TypeCode.Int16 => DbType.Int16,        TypeCode.UInt16 => DbType.UInt16,        TypeCode.Int32 => DbType.Int32,        TypeCode.UInt32 => DbType.UInt32,        TypeCode.Int64 => DbType.Int64,        TypeCode.UInt64 => DbType.UInt64,        TypeCode.Single => DbType.Single,        TypeCode.Double => DbType.Double,        TypeCode.Decimal => DbType.Decimal,        TypeCode.Boolean => DbType.Boolean,        TypeCode.String => DbType.String,        TypeCode.Char => DbType.StringFixedLength,        TypeCode.DateTime => DbType.DateTime,        _ => DbType.Object,

/// 构造参数 /// </summary> /// <param name="valueType"> </param> /// <returns> </returns> DbParameter CreateParameter( Type valueType) ; /// <summary> /// 构造参数 /// </summary> /// <param name="name"> </param> /// <param name="valueType"> </param> /// <returns> </returns> DbParameter CreateParameter( string name, Type valueType) ;nbczhibo.com

// <summary> /// 构造参数 /// </summary> /// <param name="builder"> </param> /// <param name="parameterName"> </param> /// <param name="value"> </param> /// <returns> </returns> public Expression Create( IEmitBuilder builder, Expression parameterName, Expression value) {     // var parameter = command.CreateParameter();     // parameter.ParameterName = parameterName;     var parameter = _parameterBuilder.New(builder, parameterName);     // parameter.DbType = dbType;    _parameterBuilder.SetDbType(builder, parameter, CheckDbTypeCore( value .Type));     // parameter.Value = value;    _parameterBuilder.SetValue(builder, parameter, value );ttzb.ln.cn


  /// </summary>     /// <param name="name"> </param>     /// <param name="valueType"> </param>     /// <returns> </returns>     public DbParameter GetProtoType( string name, Type valueType)    {         var key = new NameTypedCacheKey(name, valueType);         if (_protoTypes.TryGetValue(key, out var cached))             return cached; # if NET9_0_OR_GREATER         lock (_lock) # else         lock (_protoTypes) # endif        {             if (_protoTypes.TryGetValue(key, out cached))                 return cached;             return _protoTypes[key] = _factory.CreateParameter(name, valueType);


/// </summary>     /// <param name="valueType"> </param>     /// <returns> </returns>     public CollectParameterPrototype GetProtoType( Type valueType)    {         if (_protoTypes.TryGetValue(valueType, out var protoType))             return protoType; # if NET9_0_OR_GREATER         lock (_lock) # else  nbczhibo.com         lock (_protoTypes) # endif        {             if (_protoTypes.TryGetValue(valueType, out protoType))                 return protoType;             var parameter = _factory.CreateParameter(valueType); ftzhibo.com            return _protoTypes[valueType] = new (_original, parameter, _cloneConverter);


ar dataSource = new MySqlDataSource(ConnectionString); var builder = ShadowBuilder.CreateCache(Mapper.Default, engine, dataSource); var select = table.ToQuery()    .And(table.Id.Equal())    .ToSelect()



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3108998/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-01-07

  • 博文量
    108
  • 访问量
    102111