Linq to Entities日期时间转换

4

如果我有一个DateTime类型的字符串实体,我想用LINQ to Entities在日期上过滤数据,有哪些选项可供选择?

它似乎不支持我进行DateTime转换。

基本上,我想要实现:

var filtered = from item in entities.itemsSet
               where Convert.ToDateTime(shift.starttime) >= startDate 
                   && Convert.ToDateTime(shift.endtime) < endDate
               select item;

我的选择有哪些可以实现这个目标?

你遇到了什么样的错误,如果有的话? - BlackICE
基本上是这样的:“Linq to entities不支持(Convert.ToDateTime(String))…” - LB.
3个回答

6

使用 System.Data.Objects.SqlClient.SqlFunctions

有一个名为 DateDiff 的函数,它有多个重载可以接受日期字符串。

SqlFunctions 类中的所有函数都编译为 SQL 语句,并且只能在 Linq to entities 中使用。

[EdmFunctionAttribute("SqlServer", "DATEDIFF")]
public static Nullable<int> DateDiff(string datePartArg, string startDate, string endDate)

http://msdn.microsoft.com/en-us/library/dd466158.aspx

您需要传入一个字符串,例如 "day" 作为第一个参数来指定要比较的日期部分。该函数直接映射到 SQL 函数 DATEFIFF:

http://msdn.microsoft.com/en-us/library/ms189794.aspx

对于 Linq to SQL,有一个类似的类,请注意。


太好了!当使用linq-to-entities在一个varchar列中查询日期比较时,这拯救了我。 - anewcomer

3
你最终会使用内存过滤。
//So first select your data

var data= (from item in entities.itemsSet).ToList();


//Then filter
var filtered = from item in data
           where Convert.ToDateTime(shift.starttime) >= startDate 
               && Convert.ToDateTime(shift.endtime) < endDate
           select item;

另一个选择是创建一个存储过程来为您完成。在存储过程中,您需要将开始/结束时间与转换为日期时间的日期时间字符串进行比较。


1
我喜欢这个。虽然可能存在扩展问题,但这将起作用。SP方式可能是正确的方式。 - LB.
只是提醒一下,上面的代码可以简化为一个查询... 只需执行 var filtered = (select item from entities.itemsSet.AsEnumarable() - Nix
我们只能以只读方式访问它,因为他们不会更改他们的模式。 - LB.
不确定我是否理解你的问题?当我说将它们转换为对象时,它们仍然是实体,我的意思是从数据库中选择它们,然后进行筛选。 - Nix
太好了...我已经尝试过很多次在我的linq to entities查询中使用Convert.TodateTime,但它对我不起作用...... - Glory Raj
显示剩余3条评论

2

我也遇到了同样的问题,因为当前的Sql Server数据提供程序对EF忽略了将DateTime.Parse转换为CAST(varField As DateTime)。

因此,为了构建一个可以成功转换为存储表达式的表达式树,我应用了以下内容,它的行为与谓词所期望的行为相同:DateTime.Parse(x.DateField) == DateConstraint

注意,“Client”对象包含用于生成谓词以在EFQuery.Where(predicate)中使用的输入参数。

if (client.DateOfBirth.HasValue) // can't find a string <-> DateTime conversion syntax with EF support

         {

            var day = client.DateOfBirth.Value.Day.ToString().PadLeft(2, '0');

            var month = client.DateOfBirth.Value.Month.ToString().PadLeft(2, '0');

            var year = client.DateOfBirth.Value.Year.ToString();

            // very verbose, but apparently there's no EF support for String to DateTime conversion

            spec = spec.And(c => SqlFunctions.IsDate(c.DateOfBirth).HasValue && SqlFunctions.IsDate(c.DateOfBirth).Value == 1

               && c.DateOfBirth.StartsWith(day)

               && month == (c.DateOfBirth.Contains("-") || c.DateOfBirth.Contains("/")

               ? c.DateOfBirth.Substring(c.DateOfBirth.Contains("-") ? c.DateOfBirth.IndexOf("-") + 1 : c.DateOfBirth.Contains("/")

               ? c.DateOfBirth.IndexOf("/") + 1 : 0, 2) : "f")

               && c.DateOfBirth.EndsWith(year));

         }

正如您所看到的,上述内容对日期的日、月、年组成部分进行字符串匹配,并期望以 DD/MM/YYYY 的形式表示(澳大利亚!澳大利亚!澳大利亚!)。它可以很容易地修改为适用于不同的日期表示形式和/或包含时间组件的约束。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接