C# 系统。反思,如何获得场&场;财产状况?

C# 系统。反思,如何获得场&场;财产状况?,c#,reflection,position,propertyinfo,fieldinfo,C#,Reflection,Position,Propertyinfo,Fieldinfo,问题:我使用下面的类将csv文件序列化为 列表 然后我使用 MyConvertTo (也列在下面)。 现在的问题是,MyConvertTo会更改列的位置,这意味着所有属性都会出现 毕竟是公共变量 这导致的问题是,之后我使用SqlBulkCopy将DataTable复制到数据库表中。 不幸的是,SqlBulkCopy使用列的索引而不是列名进行自动映射 数据表到数据库表 这意味着我会收到很好的错误消息,因为它试图插入字母数字的AP\u FL\u CADKey 在float区域字段中(因为我的数据库表

问题:我使用下面的类将csv文件序列化为

列表

然后我使用

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我认为我的解决方案简单实用。