Получение минимума - Min () - для столбца DateTime в DataTable с использованием LINQ to DataSets? - PullRequest
0 голосов
/ 24 апреля 2010

Мне нужно получить минимальное значение DateTime столбца в DataTable. DataTable генерируется динамически из файла CSV, поэтому я не знаю имя этого столбца до времени выполнения. Вот код, который у меня есть, который не работает ...

private DateTime GetStartDateFromCSV(string inputFile, string date_attr)
{
    EnumerableRowCollection<DataRow> table = CsvStreamReader.GetDataTableFromCSV(inputFile, "input", true).AsEnumerable();
    DateTime dt = table.Select(record => record.Field<DateTime>(date_attr)).Min();
    return dt;
}

Таблица переменных разбита просто для ясности. В основном мне нужно найти минимальное значение в виде DateTime для одного из столбцов (которое должно быть выбрано во время выполнения и представлено date_attr).

Я пробовал несколько решений SO (большинство имеет дело с известными столбцами и / или полями, отличными от DateTime). То, что я получил, выдает ошибку во время выполнения, сообщая мне, что он не может выполнить преобразование DateTime (что, похоже, проблема с Linq?)

Я подтвердил, что данные для имени столбца в строке date_attr являются значением даты.

ОБНОВЛЕНИЕ: Stacktrace согласно запросу:

System.InvalidCastException was unhandled by user code
  Message="Specified cast is not valid."
  Source="System.Data.DataSetExtensions"
  StackTrace:
       at System.Data.DataRowExtensions.UnboxT`1.ValueField(Object value)
       at System.Data.DataRowExtensions.Field[T](DataRow row, String columnName)
       at Presenter.Views.NetworkVisualizationDetailPresenter.<>c__DisplayClass1.<GetStartDateFromCSV>b__0(DataRow t) in Presenter\Views\NetworkVisualizationDetailPresenter.cs:line 194
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Linq.Enumerable.Min[TSource](IEnumerable`1 source)
       at System.Linq.Enumerable.Min[TSource,TResult](IEnumerable`1 source, Func`2 selector)
       atPresenter.Views.NetworkVisualizationDetailPresenter.GetStartDateFromCSV(String inputFile, String date_attr) in Presenter\Views\NetworkVisualizationDetailPresenter.cs:line 194
       at Presenter.Views.NetworkVisualizationDetailPresenter.GetDynamicNetworkVisualizationData(String inputFile, Int32 dataMode, Int32 timeInterval, String date_attr, String entity_attr, String event_attr) in Views\NetworkVisualizationDetailPresenter.cs:line 123
       at Presenter.Views.NetworkVisualizationDetail.Page_Load(Object sender, EventArgs e) in NetworkVisualizationDetail.aspx.cs:line 114
       at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
       at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
       at System.Web.UI.Control.OnLoad(EventArgs e)
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
  InnerException: 

1 Ответ

1 голос
/ 24 апреля 2010

На самом деле кажется, что ваша проблема не в Linq, а в данных в вашей таблице данных. Если ваша ошибка гласит, что преобразование DateTime невозможно, ваша ошибка, скорее всего, будет сгенерирована здесь:

record.Field<DateTime>(date_attr)

которого нет в Linq.

Убедитесь, что все ваши строки имеют правильное значение в этом столбце. Кроме того, если бы вы могли вывести свою трассировку стека из исключения, это помогло бы.

UPD: Глядя на обновление трассировки стека, я вижу в нем две верхние записи:

at System.Data.DataRowExtensions.UnboxT`1.ValueField(Object value)
at System.Data.DataRowExtensions.Field[T](DataRow row, String columnName)

Это наиболее точно подтверждает, что проблема не в linq, а в реальных данных, которые вы пытаетесь преобразовать. Второй вызов - это сообщение об исключении, определенно проблема преобразования данных:

Сообщение = "Указанное приведение недействительно."

Я только что дважды проверил, этот код будет работать с данными, если тип столбца DateTime.

table.Select(record => record.Field<DateTime>(date_attr)).Min();

Но если тип столбца - строка - он выдает исключение, которое вы получаете, с той же трассировкой стека! :)

Измените его на это, и вы не должны получать никаких ошибок (если вы считаете, что ваши данные верны):

table.Select(record => Convert.ToDateTime(record[date_attr])).Min();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...