2015-03-03 46 views
0

我有一個VS2010項目,它具有從SQL 2008數據庫生成的Linq-to-SQL類。在關於表中有一個特殊的創建的列,此式柱具有類型DATETIMEOFFSET(3),並且被用作每天的基礎上的partioning鍵:如何使用Linq-to-sql指定DateTimeOffset精度

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到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-to-sql生成DateTimeOffset(3)作爲SQL變量類型或使分區消除有效的另一種方法來聽到其他可能性。

PS:我已簡化了表定義和查詢短問題定義。

+0

.NET使用的7規模,要使用3 ... ...妥協忽視的問題,看看他們的解決方案...... http://stackoverflow.com/questions/510384/how -do-i-stop-datetimeoffset-scale-from-cause-a-changeconflictexception -in – 2015-03-03 12:19:48

回答

0

根據需要使用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 
+0

感謝你的回答,我知道如何擺脫dotnet精度。但我想看到的是一種將dotnet DateTimeOffset轉換爲sql DateTimeOffset(3)而不是DateTimeOffset(7)的方法。 – Ako 2015-03-03 12:42:47

+0

@Ako你有一個DBML文件嗎?這有點矯枉過正,但你有沒有想過創建一個自定義類型映射? https://msdn.microsoft.com/en-us/library/vstudio/cc716764%28v=vs.100%29.aspx – 2015-03-03 14:46:10

+0

謝謝保羅,我會檢查出來。 DBML中的類型向前移動: < Column Name =「Created」Type =「System.DateTimeOffset」DbType =「DateTimeOffset NOT NULL」IsPrimaryKey =「true」CanBeNull =「false」/> – Ako 2015-03-03 15:08:30