求助.GetType().GetProperty(column.ColumnName)获取不到值。

qluq1101 2014-01-26 01:19:02


public static T CreateItem<T>(DataRow row)
{
T obj = default(T);
//object value;
if (row != null)
{
obj = Activator.CreateInstance<T>();

foreach (DataColumn column in row.Table.Columns)
{
PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);
try
{
object value = row[column.ColumnName];
prop.SetValue(obj, value, null);
//prop.SetValue(obj, Convert.ChangeType(value, prop.PropertyType), null);
//value = null;
//prop = null;
}
catch
{
// You can log something here
throw;
}
}
}

return obj;
}



这是代码,问题如下:

在foreach循环中第一次
PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);//column.ColumnName为“PK_ID”,主键,int型,自增;

可以获取到正确的值,但是在执行第二次该语句时,column.ColumnName值为“P_Content”,string 型的,此时prop获取的值就为NULL了。

求解这是怎么回事?又该如何解决?
...全文
727 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhqiao87 2015-08-10
  • 打赏
  • 举报
回复
public static Type GetPropertyInfoType(PropertyInfo pi) { bool isNullableValueType = pi.PropertyType.IsGenericType && (pi.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)); Type genericType = pi.PropertyType; if (isNullableValueType) genericType = pi.PropertyType.GetGenericArguments()[0]; return genericType; } //你的代码中这样调用 PropertyInfo pi = type.GetProperties().First(q => string.Equals(q.Name, dt.Columns[i].ColumnName, StringComparison.OrdinalIgnoreCase)); Type pit = ReflectionHelper.GetPropertyInfoType(pi); object value = Convert.ChangeType(item[i], pit); pi.SetValue(obj, value, null);
md5e 2014-01-26
  • 打赏
  • 举报
回复
一般可以写一个方法,根据<t>的类型,将value强制转成相应类型 private object GetValue(object value, string DeclaringType) { switch (DeclaringType.ToLower()) { case "string": return value.ToString(); case "int64": return Utils.StrToInt(value, 0); case "int32": return Utils.StrToInt(value, 0); case "int16": return Utils.StrToInt(value, 0); case "int": return Utils.StrToInt(value, 0); case "bool": return Utils.StrToBool(value, false); case "double": return Utils.StrToFloat(value, 0); case "float": return Utils.StrToFloat(value, 0); case "datetime": return Utils.StrToDatetTime(value.ToString()); case "decimal": return Utils.StrToFloat(value, 0); } return ""; }
qluq1101 2014-01-26
  • 打赏
  • 举报
回复
引用 12 楼 liuchaolin 的回复:
[quote=引用 11 楼 qluq1101 的回复:] [quote=引用 10 楼 liuchaolin 的回复:] [quote=引用 9 楼 qluq1101 的回复:] [quote=引用 8 楼 liuchaolin 的回复:] prop.SetValue(obj, row[column.ColumnName].ToString(), null);
列有多种数据类型的。 ColumnName为string的时候这样当然不错,但是为int的时候row[column.ColumnName].ToString()赋值会不会又出现类型不对的错误?[/quote] object是任何数据类型都可以,不用管[/quote] “类型“System.String”的对象无法转换为类型“System.Int32””


PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);


//////////////////////////////////

 prop.SetValue(obj, value, null);

此处prop已经获取了obj.GetType()的类型了,你在prop.SetValue中全部转成string是不行的吧?[/quote] 如果不转可以不? prop.SetValue(obj, row[column.ColumnName], null);[/quote] 不转不又是以前那个错误? 类型“System.DBNull”的对象无法转换为类型“System.String” 不过我现在解决问题了。



PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);
                    try
                    {
                        object value = row[column.ColumnName];
                        if (column.DataType == typeof(System.String))
                        {
                            value = row[column.ColumnName].ToString();
                        }
                        prop.SetValue(obj, value, null);
                        
                    }
                    catch
                    {
                        // You can log something here  
                        throw ;
                    }


加入这个判断后就解决问题了。
md5e 2014-01-26
  • 打赏
  • 举报
回复
引用 11 楼 qluq1101 的回复:
[quote=引用 10 楼 liuchaolin 的回复:] [quote=引用 9 楼 qluq1101 的回复:] [quote=引用 8 楼 liuchaolin 的回复:] prop.SetValue(obj, row[column.ColumnName].ToString(), null);
列有多种数据类型的。 ColumnName为string的时候这样当然不错,但是为int的时候row[column.ColumnName].ToString()赋值会不会又出现类型不对的错误?[/quote] object是任何数据类型都可以,不用管[/quote] “类型“System.String”的对象无法转换为类型“System.Int32””


PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);


//////////////////////////////////

 prop.SetValue(obj, value, null);

此处prop已经获取了obj.GetType()的类型了,你在prop.SetValue中全部转成string是不行的吧?[/quote] 如果不转可以不? prop.SetValue(obj, row[column.ColumnName], null);
qluq1101 2014-01-26
  • 打赏
  • 举报
回复
引用 10 楼 liuchaolin 的回复:
[quote=引用 9 楼 qluq1101 的回复:] [quote=引用 8 楼 liuchaolin 的回复:] prop.SetValue(obj, row[column.ColumnName].ToString(), null);
列有多种数据类型的。 ColumnName为string的时候这样当然不错,但是为int的时候row[column.ColumnName].ToString()赋值会不会又出现类型不对的错误?[/quote] object是任何数据类型都可以,不用管[/quote] “类型“System.String”的对象无法转换为类型“System.Int32””


PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);


//////////////////////////////////

 prop.SetValue(obj, value, null);

此处prop已经获取了obj.GetType()的类型了,你在prop.SetValue中全部转成string是不行的吧?
md5e 2014-01-26
  • 打赏
  • 举报
回复
引用 9 楼 qluq1101 的回复:
[quote=引用 8 楼 liuchaolin 的回复:] prop.SetValue(obj, row[column.ColumnName].ToString(), null);
列有多种数据类型的。 ColumnName为string的时候这样当然不错,但是为int的时候row[column.ColumnName].ToString()赋值会不会又出现类型不对的错误?[/quote] object是任何数据类型都可以,不用管
qluq1101 2014-01-26
  • 打赏
  • 举报
回复
引用 8 楼 liuchaolin 的回复:
prop.SetValue(obj, row[column.ColumnName].ToString(), null);
列有多种数据类型的。 ColumnName为string的时候这样当然不错,但是为int的时候row[column.ColumnName].ToString()赋值会不会又出现类型不对的错误?
md5e 2014-01-26
  • 打赏
  • 举报
回复
prop.SetValue(obj, row[column.ColumnName].ToString(), null);
qluq1101 2014-01-26
  • 打赏
  • 举报
回复
引用 4 楼 liuchaolin 的回复:
[quote=引用 2 楼 qluq1101 的回复:] [quote=引用 1 楼 liuchaolin 的回复:] 注意大小写须要一致才行
已经确认了,数据库的列是P_Content,column.ColumnName的值也是P_Content[/quote] <T>的属性也是?[/quote] 还真是要确认大小写一直才行。多谢你! 但我目前有别的问题了: object value = row[column.ColumnName]; 这一句中,ColumnName列本身是string类型的,但是允许空,所以数据库里面是null显示的;通过这一句取出来的恐怕是空值, 报错显示是“类型“System.DBNull”的对象无法转换为类型“System.String”” 奇怪的是: 此时value的值是 {} 这样的(在VS中断点查看的),我想加个判断语句判断其为空然后赋值string的空值“” ,但是却无法判断, if (value == "{}") 或者 if (value == null ) 或者 if (value == "") 均不能进入下一步赋值语句,该如何办?
Regan-lin 2014-01-26
  • 打赏
  • 举报
回复
T obj的定义的列名是否对应column.ColumnName的名字
qluq1101 2014-01-26
  • 打赏
  • 举报
回复
引用 4 楼 liuchaolin 的回复:
[quote=引用 2 楼 qluq1101 的回复:] [quote=引用 1 楼 liuchaolin 的回复:] 注意大小写须要一致才行
已经确认了,数据库的列是P_Content,column.ColumnName的值也是P_Content[/quote] <T>的属性也是?[/quote] 这……我去看看先
md5e 2014-01-26
  • 打赏
  • 举报
回复
引用 2 楼 qluq1101 的回复:
[quote=引用 1 楼 liuchaolin 的回复:] 注意大小写须要一致才行
已经确认了,数据库的列是P_Content,column.ColumnName的值也是P_Content[/quote] <T>的属性也是?
  • 打赏
  • 举报
回复
PropertyInfo props = obj.GetType().GetProperties().ToDictionary(p => p.Name, p => p, StringComparer.OrdinalIgnoreCase);
PropertyInfo prop;
foreach (DataColumn column in row.Table.Columns)
{
     if(props.TryGetValue(column.ColumnName, out prop))
     {
          try
                    {
                        object value = row[column.ColumnName];
                        prop.SetValue(obj, value, null);
                        //prop.SetValue(obj, Convert.ChangeType(value, prop.PropertyType), null);
                        //value = null;
                        //prop = null;
                    }
                    catch
                    {
                        // You can log something here  
                        throw;
                    }
     }
}
qluq1101 2014-01-26
  • 打赏
  • 举报
回复
引用 1 楼 liuchaolin 的回复:
注意大小写须要一致才行
已经确认了,数据库的列是P_Content,column.ColumnName的值也是P_Content
md5e 2014-01-26
  • 打赏
  • 举报
回复
注意大小写须要一致才行

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧