Linq to Entities DateTime转换

时间:2010-03-31 19:35:13

标签: linq datetime linq-to-entities

如果给定一个将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;

我有什么选择来实现这个目标?

3 个答案:

答案 0 :(得分:6)

使用System.Data.Objects.SqlClient.SqlFunctions

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

SqlFunctions类中的所有函数都编译成SQL语句,并且只能在Linq中用于实体。

[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有一个类似的类,只是警告你。

答案 1 :(得分: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;

另一种选择是创建一个存储过程来为您完成。在SP中你必须采取开始/结束,然后将它与你的日期时间字符串作为日期时间进行比较。

答案 2 :(得分:1)

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

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

注意'Client'对象包含用于生成Predicate的输入参数,用于:EFQuery.Where(谓词)

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表示(Aussie Aussie Aussie!)。它可以很容易地修改为使用不同的日期表示和/或包括时间组件的约束。