如何使用Linq将DateTimeOffset精度指定为Sql



我有一个VS2010项目,其中包含从SQL 2008数据库生成的Linq到SQL类。相关表有一个特殊的Created列,该列的类型为datetimeoffset(3),每天用作分区键:

CREATE TABLE [dbo].[tableA](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Created] [datetimeoffset](3) NOT NULL,
    [A] [int] NULL,
 CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED 
(
    [Created] ASC,
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) on partScheme_Daily_OnCreatedDate (Created)
) on partScheme_Daily_OnCreatedDate (Created)

为此列生成的linq-to-SQL代码将DateTimeOffset显示为其类型。

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.TableA")]
public partial class TableA : INotifyPropertyChanging, INotifyPropertyChanged {
    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
    private int _Id;
    private System.DateTimeOffset _Created;
    etc

我可以基于生成的类创建并执行linq-to-sql查询。

var query = db.TableA.Where(pt => pt.Created >= (DateTimeOffset) startTime && pt.Created <= endTime

这将转换为正确的SQL查询,但SQL端的类型为DateTimeOffset(7)。因此,数据库不使用最佳分区消除,而是访问所有分区。如果我根据捕获的SQL查询更改类型DateTimeOffset(3)并在SSMS中执行,它将使用分区消除。

exec sp_executesql N'SELECT TOP (10001) [t0].[Id], [t0].[Created], 
FROM [dbo].[TableA] AS [t0]
WHERE ([t0].[Created] >= @p0) AND ([t0].[Created] <= @p1) 
ORDER BY [t0].[Created] DESC',N'@p0 datetimeoffset(3),@p1 datetimeoffset(3)',@p0='2015-02-27 23:00:00 +00:00',@p1='2015-03-03 22:59:59 +00:00'

那么如何获得最优分区消除呢?在我的示例中,我最多需要访问2个分区。

我曾想过创建一个存储过程,但这意味着我失去了在c#代码中轻松更改查询的灵活性。另一个解决方案是将Created列的SQL类型更改为DateTimeOffset(7)。但这样做的缺点是存储冗余的精度数据,而我实际上没有这些数据。

我想听听其他的可能性,要么通过指示linq将DateTimeOffset(3)作为sql变量类型进行sql生成,要么通过另一种方式使分区消除变得高效。

附言:我已经简化了表格定义和查询的简短问题定义。

根据需要使用DateTimeOffset.ToString格式。

DateTimeOffset outputDate = new DateTimeOffset(2007, 11, 1, 9, 0, 0, 
                                 new TimeSpan(-7, 0, 0)); 
string format = "dddd, MMM dd yyyy HH:mm:ss zzz";
// Output date and time using custom format specification
Console.WriteLine(outputDate.ToString(format, null as DateTimeFormatInfo));
Console.WriteLine(outputDate.ToString(format, CultureInfo.InvariantCulture));
Console.WriteLine(outputDate.ToString(format, 
                                  new CultureInfo("fr-FR")));
Console.WriteLine(outputDate.ToString(format, 
                                  new CultureInfo("es-ES")));
// The example displays the following output to the console: 
//    Thursday, Nov 01 2007 09:00:00 -07:00 
//    Thursday, Nov 01 2007 09:00:00 -07:00 
//    jeudi, nov. 01 2007 09:00:00 -07:00 
//    jueves, nov 01 2007 09:00:00 -07:00

相关内容

  • 没有找到相关文章

最新更新