3

私はDataTableとを持っていModelます。クラスのメンバーに列をマップする方法は他にありますか? 私の現在の方法を説明しましょう。

クラス モデル

private class MyModel
{
    public int ModelID { get; set; }
    public string ModelName { get; set; }
}

およびDataTable次のデータ列を持つ a、

ModelID   |   ModelName 

レコードDatatableは、SQL クエリの結果からのものです。

SELECT ModelID, ModelName FROM tableName

ここで、レコードを にマップするとIList<MyModel> myListforeachループが実行されます。

foreach (DataRow row in MyDataTable)
{
    MyModel model = new MyModel()
    model.ModelID = Convert.ToInt32(row["Position"].ToString());
    model.ModelName = row["ModelName"].ToString(); 
    myList.Add(model);
}

これは完全に正常に機能します。これは実際には問題ではありませんが、多くのデータ テーブルがあり、 20 列以上、さらに多くのクラスがあることを考えると、非常に時間がかかります。

私が探しているのは、それを行う他の方法があるかどうかです。既存のクラスのようですが、その名前が本当にわかりません。

この質問が既にされている場合は、リンクを見つけるのを手伝ってください。

ありがとうございました。

4

2 に答える 2

2

AutoMapperはこれを実行できるはずですが、その効率性をテストする必要があります。 この投稿は、いくつかの成功を収めているようです。

public class Person
{
    public string First_Name { get; set; }
    public string Last_Name { get; set; }
    public string User_Name { get; set; }
}

List<Person> people = AutoMapper.Mapper.DynamicMap<IDataReader, 
                      List<Person>>(sourceDataTable.CreateDataReader());

ボンネットの下では、おそらく既に行っていることと非常に類似したことを行っていることに注意してください。ただし、いくつかの反射を混ぜて、より一般的なものにしています。あなたがやっていることは、それ自体が非常に非効率的というわけではありませ.

DataTable完全に ORM に 置き換えることもできます。Entity Frameworkはかなり一般的な標準ですが、他にも多くの標準があります。( Dapperは、高速なパフォーマンスで知られています。それが必要な場合)。

「時間がかかる」部分が実行時のパフォーマンスではなく開発時間である場合、私はそれについてあまり心配しません。翻訳レイヤーの背後にある を POCO オブジェクトに抽象化することに時間を費やすことができればDataTable、長期的にはそのメリットが報われる可能性があります。単純なコードがたくさんありますが、1 回限りの費用です。

于 2013-10-02T13:13:42.497 に答える
0

これを使用できます。

public static List<T> ToModel<T>(this DataTable dt)
    {
        List<string> columns = (from DataColumn dc in dt.Columns select dc.ColumnName).ToList();

        var fields = typeof(T).GetFields();
        var properties = typeof(T).GetProperties();

        List<T> lst = new List<T>();

        foreach (DataRow dr in dt.Rows)
        {
            var ob = Activator.CreateInstance<T>();

            foreach (var fieldInfo in fields.Where(fieldInfo => columns.Contains(fieldInfo.Name)))
            {
                fieldInfo.SetValue(ob, !dr.IsNull(fieldInfo.Name) ? dr[fieldInfo.Name] : fieldInfo.FieldType.IsValueType ? Activator.CreateInstance(fieldInfo.FieldType) : null);
            }

            foreach (var propertyInfo in properties.Where(propertyInfo => columns.Contains(propertyInfo.Name)))
            {
                propertyInfo.SetValue(ob, !dr.IsNull(propertyInfo.Name) ? dr[propertyInfo.Name] : propertyInfo.PropertyType.IsValueType ? Activator.CreateInstance(propertyInfo.PropertyType) : null);
            }

            lst.Add(ob);
        }

        return lst;
    }
于 2015-07-28T08:27:02.077 に答える