不支持 Linq-to-EF DateTime.ToLocalTime

Posted

技术标签:

【中文标题】不支持 Linq-to-EF DateTime.ToLocalTime【英文标题】:Linq-to-EF DateTime.ToLocalTime not supported 【发布时间】:2012-05-12 22:24:02 【问题描述】:

Linq to EF 不支持DateTime.ToLocalTime

还有什么选择?我想不通了。

【问题讨论】:

Linq to SQL 和实体框架不是一回事。你用的是哪个? Linq2Sql 和 Linq2EF 是两个独立的产品。是哪一个? 您如何尝试使用 ToUniversalTime - 在 where 子句或 select 中? 对不起,我正在尝试使用 ToLocalTime() 方法。 @DanFitch - 你能做的最好的就是自定义函数,比如我的SQL Server Time Zone Support 项目中的函数。从 EF 调用会有些困难。不过,最好提出一个新问题,以便其他人可以提出创意。这里的这个特殊问题只是为了避免这种情况,就像菲尔在他的回答中所写的那样。 【参考方案1】:

不要在 Linq 查询中使用 .ToLocalTime(),而是在查询之外对参数使用相反的转换。

var dateUniversal = dateParam.ToUniversalTime();

var query = myTable.Where( t => t.DateTime > dateUniversal );

【讨论】:

这不起作用。 ToUniversalTime() 必须在 linq 查询中,因为时间来自每个数据库记录。 如果 UTC 存储在数据库中,那么如果您的参数是 UTC,它应该可以工作 - 确定吗?【参考方案2】:

通常,您应该在数据库中以 UTC 格式存储日期和时间。

将代码中的任何本地日期/时间转换为 UTC,然后再将它们存储到数据库中。

同样,如果你需要在数据库中显示来自 UTC 的本地时间,则在数据库获取后将其转换为代码。

【讨论】:

我知道这一点。我需要做一个特殊情况,发现我是否可以使用 linq 运行 .ToUniversalTime() 或 .ToLocalTime() 如您所见,这不是一个好主意。通过修复“特殊情况”,您可能会做得更好。 HTH。 @in_visible “特殊情况”通常也被其他编码人员称为“wtf”。【参考方案3】:

我使用了扩展组合以及依赖于从我的应用前端传递的值在 LocalTime 中的组合。所以,如果我有两个日期时间......比如......报告的开始日期和结束日期参数,我会把它们放在那里......让用户在 LocalTime 提交......然后在我的控制器的后端部分.. 我会在我的 Linq to Entities 查询中使用 sdate 和 edate 变量。我将静态扩展方法放入静态帮助程序类中。对不起,我迟到了一年多。 :)

    DateTime sdate = CalcHelper.AbsoluteStart(model.StartDate);
    DateTime edate = CalcHelper.AbsoluteEnd(model.EndDate);

    public static DateTime AbsoluteStart(this DateTime dateTime)
    
        return dateTime.Date.ToUniversalTime();
    
    public static DateTime AbsoluteEnd(this DateTime dateTime)
    
        return AbsoluteStart(dateTime).AddDays(1).AddTicks(-1).ToUniversalTime();
    

【讨论】:

【参考方案4】:

如果您从服务器获取时区偏移量,您也许可以使用 EntityFunctions 在 linq 查询中应用偏移量

var offset = TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes;
var result = db.Dates.Where(a => 
             EntityFunctions.DiffDays(EntityFunctions.AddMinutes(a.Date, offset), DateTime.Now) == 0);

【讨论】:

【参考方案5】:

你可以这样试试:

var promotions = _promotionService.GetAll(
            x => (DbFunctions.TruncateTime(x.CreatedDate.Value) >= viewModel.GTXFromDate.Date)
            && (DbFunctions.TruncateTime(x.CreatedDate.Value) <= viewModel.GTXToDate.Date));

【讨论】:

【参考方案6】:

将DateTime转为String进行比较,例如:

const string DATE_FORMAT = "yyyy/MM/dd";
var query = sampleTable.Where(x => x.DateTime.ToString(DATE_FORMAT) > DateTime.Now.ToString(DATE_FORMAT));

【讨论】:

这种字符串比较技巧可能适用于Where 子句;不过,你会如何为GroupBy 做类似的事情?【参考方案7】:

在question找到解决方案

public partial class Person  

  partial void OnLoaded()  
    this._BirthDate = DateTime.SpecifyKind(this._BirthDate, DateTimeKind.Utc); 
   
 

【讨论】:

收到此错误。 LINQ to Entities 无法识别方法 'System.DateTime SpecifyKind(System.DateTime, System.DateTimeKind)' 方法,并且此方法无法转换为存储表达式。

以上是关于不支持 Linq-to-EF DateTime.ToLocalTime的主要内容,如果未能解决你的问题,请参考以下文章

C# json日期转换

如何将 python 日期时间转换为具有可读格式日期的字符串?

XSLT日期时间处理

程序中的tostring()函数到底是用来做啥的,转化成字符我是知道的,

C# 计算两个日期的时间间隔

我正在尝试使用 pandas TimeGrouper 创建一些日期的频率表,但是它返回错误