1. ホーム
  2. シーピー

GetProperty リフレクションの代入 SetValue エラーです。System.Byte "型のオブジェクトは "System.Nullable`1[System.Int32]"型に変換することができません。Int32]」に変換できません。

2022-03-03 09:36:55
<パス

エンティティ変換のためにデータベースのDataTableを読み込む際にエラーが報告されますが、データベースの型はtinyint,nullで、エンティティクラスの型はintでしょうか。
元のエラーコードはこのようなものです。

       private static void GetPropertyInfo<T>(DataTable table, Type type, int i, T item) where T : class
        {
            try
            {
                PropertyInfo Property;
                object RowCol;
                foreach (DataColumn column in table.Columns)
                Columns) {
                    RowCol = table.Rows[i][column];
                    Property = type.GetProperty(column.ColumnName);
                    If ((RowCol ! = DBNull.Value) && (Property ! = null))
                    {
                        Property.SetValue(item, table.Rows[i][column], null);// error reported here
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                throw;
            }
        }


いくつかの記事を参考にしたところ、リフレクション時に内部で制限をかけると、stringからint、byteからnullableがエラーとして報告されることがわかりました。これに対する解決策は2つあります。
1. 正しい型に設定する。例えば、データベースがtinyint,nullの場合、クラス型はbyte? これは、形式を厳密にチェックするために推奨される方法です。
2. 値を設定する場合、まず型変換を行いますが、これは一般型とNullable型を区別する必要があります、次のコードを参照してください。この方法は、怠惰になることはできますが、変換の余分な層は非常に非効率的であるため、推奨されません。

 public static object ConvertTo(object convertibleValue, Type type)
        {
            if (!type.IsGenericType)
            {
                return Convert.ChangeType(convertibleValue, type);
            }
            else
            {
                Type genericTypeDefinition = type.GetGenericTypeDefinition();
                if (genericTypeDefinition == typeof(Nullable<>))
                {
                    return Convert.ChangeType(convertibleValue, Nullable.GetUnderlyingType(type));
                }
            }
            throw new InvalidCastException(string.Format("Invalid cast from type \"{0}\" to type \"{1}\". ", convertibleValue.GetType().FullName, type.FullName));
        }

        private static void GetPropertyInfo<T>(DataTable table, Type type, int i, T item) where T : class
        {
            try
            {
                PropertyInfo Property;
                object RowCol;
                foreach (DataColumn column in table.Columns)
                Columns) {
                    RowCol = table.Rows[i][column];
                    Property = type.GetProperty(column.ColumnName);
                    If ((RowCol ! = DBNull.Value) && (Property ! = null))
                    {
                        Property.SetValue(item, ConvertTo(table.Rows[i][column], Property.PropertyType), null);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                throw;
            }
        }


参考 https://www.cnblogs.com/Chavezcn/p/7537211.html
https://q.cnblogs.com/q/3195/
https://blog.csdn.net/xiaohan2826/article/details/8536074