如果给定一个将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;
我有什么选择来实现这个目标?
答案 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!)。它可以很容易地修改为使用不同的日期表示和/或包括时间组件的约束。