Какой самый быстрый способ заполнить простой объект из DataTable?

Мне просто интересно, есть ли более быстрый или более эффективный метод для преобразования DataTable в объект?

Метод, который я сейчас использую, таков:

public class Job {
    int JobID { get; set; }
    decimal JobCost { get; set; }

    Job(DataRow dr)
    {
        ID = Convert.ToInt32(dr["ID"]);
        if(dr["JobCost "] != DBNull.Value)
            JobCost = Convert.ToDecimal(dr["DelAmt"]);
    }
}

public static List<Job> FillObjects()
{
    DataTable dtJobs = JobController.GetJobTable();

    foreach (DataRow dr in dtJobs.Rows)
    {
        jobs.Add(new Job(dr));          
    }

    return jobs
}

Это явно упрощенный пример, однако он становится довольно медленным со многими строками в таблице данных и многими свойствами в объекте. Есть ли более быстрый или более эффективный способ сделать что-то подобное?

Заранее спасибо за любые ответы!

2 ответа

Без использования Entity Framework ваши параметры ограничиваются тем, что вы уже разработали, или с помощью Linq, чтобы поместить их в свои объекты, такими как:

dtJobs.AsEnumerable().Select(x=> new Job{
                                   ID = x.Field<int>("ID"),
                                   JobCost = x.Field<Decimal>("DelAmt")
});

Это вернет множество объектов Job, которые вы затем сможете использовать для выполнения чего угодно. Одно предупреждение с вашей текущей настройкой состоит в том, что это не позволит возвращать нули. Если вы хотите сделать это, используйте нулевое десятичное поле и обрабатывайте ноль, где-либо еще.

Если порядок не важен - вы можете сделать это, используя параллель для каждого цикла по строкам данных. Это будет намного быстрее обрабатывать. Надо быть осторожным, делая это на серверном приложении.

Примечание: я обновился, чтобы заблокировать список при добавлении в него. Вы также можете использовать коллекцию из одновременных коллекций вместо блокировки.

  class Program
{
    static void Main(string[] args)
    {
        var sync = new Object();
        var dt = new DataTable();  // fill data
        var jobs = new List<Job>();
        Parallel.ForEach(dt.AsEnumerable(), row =>
        {
            var job = JobFactory.GetJob(row);
            lock (sync)
            {
                jobs.Add(job);
            }
        });
    }
}

public class JobFactory
{
    public static Job GetJob(DataRow d)
    {
        var j = new Job();

        // do processing here from data row to fill job object
        return j;
    }
}

public class Job
{

}
Другие вопросы по тегам