代码之家  ›  专栏  ›  技术社区  ›  Jay Stevens hutchonoid

使用linq to datasets为数据表中的datetime列获取最小值-min()?

  •  0
  • Jay Stevens hutchonoid  · 技术社区  · 14 年前

    我需要获取数据表中列的最小datetime值。数据表是从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字段)。我得到的结果在运行时抛出一个错误,告诉我它不能进行日期时间转换(这似乎是linq的问题?)

    我已经确认了字符串中列名的数据 小精灵 是日期值。

    更新: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 回复  |  直到 14 年前
        1
  •  1
  •   Artiom Chilaru    14 年前

    实际上,问题似乎不在linq中,而在数据表中的数据中。如果错误状态为无法进行日期时间转换,则很可能在此处生成错误:

    record.Field<DateTime>(date_attr)
    

    不在林肯。

    检查此列中所有行的值是否正确。 另外,如果您可以从异常中转储堆栈跟踪,它将有助于..

    UPD: 查看堆栈跟踪更新,可以看到其中的前两个条目:

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

    这非常肯定地证实了问题不在linq内部,而在您试图转换的实际数据中。第二个调用是异常消息,肯定是数据转换问题:

    message=“指定的强制转换无效。”

    我刚刚仔细检查了一下,如果列类型是datetime,那么这段代码可以在datatable上工作。

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

    但是,如果列类型是string,它会抛出您得到的异常,具有相同的堆栈跟踪!:)

    将其更改为此值,则不应出现任何错误(即认为您的数据有效):

    table.Select(record => Convert.ToDateTime(record[date_attr])).Min();
    
    推荐文章