C# 系统。反思,如何获得场&场;财产状况?
问题:我使用下面的类将csv文件序列化为C# 系统。反思,如何获得场&场;财产状况?,c#,reflection,position,propertyinfo,fieldinfo,C#,Reflection,Position,Propertyinfo,Fieldinfo,问题:我使用下面的类将csv文件序列化为 列表 然后我使用 MyConvertTo (也列在下面)。 现在的问题是,MyConvertTo会更改列的位置,这意味着所有属性都会出现 毕竟是公共变量 这导致的问题是,之后我使用SqlBulkCopy将DataTable复制到数据库表中。 不幸的是,SqlBulkCopy使用列的索引而不是列名进行自动映射 数据表到数据库表 这意味着我会收到很好的错误消息,因为它试图插入字母数字的AP\u FL\u CADKey 在float区域字段中(因为我的数据库表
列表
然后我使用
MyConvertTo
(也列在下面)。
现在的问题是,MyConvertTo会更改列的位置,这意味着所有属性都会出现
毕竟是公共变量
这导致的问题是,之后我使用SqlBulkCopy将DataTable复制到数据库表中。
不幸的是,SqlBulkCopy使用列的索引而不是列名进行自动映射
数据表到数据库表
这意味着我会收到很好的错误消息,因为它试图插入字母数字的AP\u FL\u CADKey
在float区域字段中(因为我的数据库表与类具有相同的布局)
是否有任何方法可以获取MyConvertTo中字段和属性的位置?
因此,我不必更改数据库表(lots)或编写自己的BulkCopy实现,
因为我不想手动设置datatable和database table之间的映射
在最坏的情况下,应该可以通过按字段偏移量排序
类别:
[FileHelpers.IgnoreFirst]
[FileHelpers.IgnoreEmptyLines]
public class MyCsvFileType
{
public string FL_CADKey;
public string FL_DWG;
public string FL_ObjID;
public string FL_Area;
public double FL_Area_double
{
get
{
if (string.IsNullOrEmpty(this.FL_Area))
return 0.0;
else
return System.Convert.ToDouble(this.FL_Area);
}
} // End Property PP_Area_double
public string AP_FL_CADKey;
public System.Guid UID
{
get
{
return System.Guid.NewGuid();
}
} // End Property UID
}
MyConvertTo:
public static DataTable MyConvertTo(dynamic custs)
{
DataTable dt = MyCreateTable(custs);
System.Data.DataRow dr = null;
foreach (dynamic cli in custs)
{
Console.WriteLine();
Type t = cli.GetType();
dr = dt.NewRow();
foreach (System.Reflection.FieldInfo fi in t.GetFields())
{
dr[fi.Name] = fi.GetValue(cli);
}
foreach (System.Reflection.PropertyInfo pi in t.GetProperties())
{
dr[pi.Name] = pi.GetValue(cli, null);
}
dt.Rows.Add(dr);
} // Next cli
return dt;
}
public static DataTable MyCreateTable(dynamic custs)
{
DataTable table = new DataTable("Table_1");
foreach (dynamic cli in custs)
{
Console.WriteLine();
Type t = cli.GetType();
foreach (System.Reflection.FieldInfo fi in t.GetFields())
{
table.Columns.Add(fi.Name, fi.FieldType);
//Console.WriteLine(fi.Name + ": " + fi.GetValue(cli));
}
foreach (System.Reflection.PropertyInfo pi in t.GetProperties())
{
table.Columns.Add(pi.Name, pi.PropertyType);
//Console.WriteLine(pi.Name + ": " + pi.GetValue(cli, null));
}
break;
} // Next cli
return table;
}
返回字段的顺序不保证相同,尽管通常是定义的顺序 我建议您使用Linq对以一致方式返回的数组进行排序,然后使用convert。您是否可以在
SqlBulkCopy
实例中设置,以添加基于列名的标识映射
如果数据源和目标表的列数相同,并且数据源中每个源列的顺序位置与相应目标列的顺序位置匹配,则不需要ColumnMappings集合。但是,如果列计数不同,或者顺序位置不一致,则必须使用ColumnMappings确保将数据复制到正确的列中
例如,添加每列时,只需调用
.add(ColumnName,ColumnName)
否,但您可以创建一个类似PositionAttribute(Position=1)的属性etc@AdrianIftode:Argh,我宁愿编写自己的序列化程序。大多数序列化程序使用基于属性的序列化来获取有关属性的元数据,classes..@Adrian Iftode:实际上,System.IntPtr x=System.Runtime.InteropServices.Marshal.OffsetOf(t,fi.Name)是可能的;如果我将struct layout everywhere设置为[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]。这对字段来说很好,但属性似乎不喜欢它……很不情愿,因为我对BulkCopy everywhere使用相同的类。这是/可能不是任何地方都需要的行为。设置[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.Layou(是的,我知道这一点。但我记得在另一个问题中,它有问题,就像jon skeet说的ot。所以我说不保证。@Quandary我认为我的解决方案简单实用。