Преобразуйте DataTable для списка <T>

У меня есть сомнение, когда-то я сделал это преобразование из DataTable кому: List<T>:

  List<EDog> lstDogs = (from drRow in dsDogs.Tables[0].AsEnumerable()
                        select new EDog()
                        {
                            intIdDog = drRow.Field<int>("IdDog"),
                            intIdOwner = drRow.Field<int?>("IdOwner"),
                            intAge = drRow.Field<int>("Age"),
                            strName = drRow.Field<string>("Name")
                       }).ToList();

Это хорошо работало, но теперь я думаю о выполнении его универсальный, так, чтобы любой тип DataSet мог быть преобразован в список со строгим контролем типов.

Как я мог сделать это универсальным? возможно, делегат, окружающий эту часть и создающий объект?

new EDog()
{
    intIdDog = drRow.Field<int>("IdDog"),
    intIdOwner = drRow.Field<int?>("IdOwner"),
    intAge = drRow.Field<int>("Age"),
    strName = drRow.Field<string>("Name")
}

Я попробовал его, но получите ошибку:

select (lambda) expected....

Какое-либо предложение?

Причина, почему мне нужно это, состоит в том, потому что каждый DataRow результата, должен быть преобразован в Объект для лучшего управления.

5
задан GEOCHET 7 January 2013 в 19:55
поделиться

3 ответа

Являются чем-то вроде этого, что вы ищете?

public static List<T> ConvertDS<T>(DataSet ds, Converter<DataRow, T> converter)
{
    return
        (from row in ds.Tables[0].AsEnumerable()
         select converter(row)).ToList();
}
6
ответ дан 18 December 2019 в 10:44
поделиться

Хорошо, давайте немного повеселимся:

public static class DataTableExtensions
{
    public static List<T> ToGenericList<T>(this DataTable datatable, Func<DataRow, T> converter)
    {
        return (from row in datatable.AsEnumerable()
                select converter(row)).ToList();
    }
}

class EDog
{
    private int intIdDog;
    private int intIdOwner;
    private int intAge;
    private string strName;

    ...

    public static EDog Converter(DataRow row)
    {
        return new EDog
                        {
                            intIdDog = (int)row["IdDog"],
                            intIdOwner = (int)row["IdOwner"],
                            intAge = (int)row["Age"],
                            strName = row["Name"] as string
                        };
    }
}

Использование:

List<EDog> dogs = dsDogs.Tables[0].ToGenericList<EDog>(EDog.Converter);

Но здесь недостаточно развлечений, верно? Как насчет этого:

class DataRowKeyAttribute : Attribute
{
    private readonly string _Key;

    public string Key
    {
        get { return _Key; }
    }

    public DataRowKeyAttribute(string key)
    {
        _Key = key;
    }
}


static class DataTableExtensions
{
    public static List<T> ToGenericList<T>(this DataTable datatable) where T : new()
    {
        return (from row in datatable.AsEnumerable()
                select Convert<T>(row)).ToList();
    }

    private static T Convert<T>(DataRow row) where T : new()
    {
        var result = new T();

        var type = result.GetType();

        foreach (var fieldInfo in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
        {
            var dataRowKeyAttribute = fieldInfo.GetCustomAttributes(typeof (DataRowKeyAttribute), true).FirstOrDefault() as DataRowKeyAttribute;
            if (dataRowKeyAttribute != null)
            {
                fieldInfo.SetValue(result, row[dataRowKeyAttribute.Key]);
            }
        } 

        return result;
    }
}

class EDog
{
    [DataRowKey("IdDog")]
    private int intIdDog;
    [DataRowKey("IdOwner")]
    private int intIdOwner;
    [DataRowKey("Age")]
    private int intAge;
    [DataRowKey("Name")]
    private string strName;

    ... 
}

Использование:

List<EDog> dogs = dsDogs.Tables[0].ToGenericList<EDog>();

И если вы хотите НАСТОЯЩИЙ развлечься, добавьте обработку ошибок, рассмотрите возможность кэширования данных отражения для повышения производительности и изменения полей на свойства.

10
ответ дан 18 December 2019 в 10:44
поделиться

Он не поддается легкому преобразованию, вы можете это сделать но, вероятно, это не сэкономит много работы.

Подумайте о внутренних знаниях в вашем примере кода: вы знаете тип и имя каждого столбца в DataTable , а также тип и имя свойства, которому он сопоставляется в типе вывода. Альтернативой было бы знать тип и индекс каждого столбца (подставляя имя для индекса). В обоих случаях вам нужно будет определить отображение, которое будет содержать эту информацию.

Альтернативой может быть создание преобразователя на основе соглашений - другими словами, имена столбцов DataTable и их целевые свойства должны быть названы согласованно, а отклонение от этого соглашения приведет к сбою преобразования. .

1
ответ дан 18 December 2019 в 10:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: