10

我有一个格式如下的表格。

PID     ID       Label        Value
------------------------------------------
1       1        First Name    Jenna
1       2        DOB           10/12/1980

我需要检索名字以 J 开头且出生日期为 10 的所有 PID。

在我的代码中,我在 C# 中的 DataTable 中检索这些,然后尝试使用 LINQ 检索我想要的结果。这只是一个例子。这些标签可以是用户定义的任何东西。

使用 LINQ,我能够检索名字以 J 开头的所有 PID,但每次我尝试为 DOB 转换值时,我都会得到 cast not valid 错误。我无法更改数据库中的列类型,因为 Value 可以包含任何类型的信息。

这是我的一段代码。我是 LINQ 的新手,仍在尝试解决它。

var resultQuery = from r in query.AsEnumerable()
where (r.Field<string>("Label") == Label  &&
r.Field<DateTime>("Value").Month == 10)
select r.Field<int>("PID");
4

2 回答 2

4

由于并非表的 Value 列中的所有项目都可以转换为DateTime,因此您所拥有的内容将在无效转换时失败。您可以添加一个子句,首先检查该值是否为 aDateTime并且仅当它是时,转换它并检查.Month属性。

DateTime d;
var resultQuery = from r in query.AsEnumerable()
                  where (r.Field<string>("Label") == Label &&
                      DateTime.TryParse(r.Field<string>("Value"), out d) && 
                      d.Month == 10)
                  select r.Field<int>("PID");

为了潜在地提高可读性,您还可以将其提取到一个单独的方法中:

var resultQuery = from r in query.AsEnumerable()
                  let d = TryGetDate(r.Field<string>("Value"))
                  where (r.Field<string>("Label") == Label &&
                      d != null && 
                      d.Month == 10)
                  select r.Field<int>("PID");

private DateTime? TryGetDate(string value)
{
    DateTime d;
    return DateTime.TryParse(value, out d) ? d : default(DateTime?);
}
于 2012-10-19T18:21:45.713 回答
2

您最终将在内存中进行过滤,这不是很有效。

所以首先选择你的数据

var data= from r in query.AsEnumerable();

然后过滤数据

var filtered = from item in data
               where item.Label == "Label"
               && Convert.ToDateTime(item.DOB).Month == 10
               select item.PID;
于 2012-10-19T18:31:14.477 回答