2016-01-20 114 views
1

我正在評估在當前項目中使用ServiceStack的OrmLite,並且需要對創建的索引進行一些控制;我希望儘可能通過數據註釋來控制這些內容。在SQL Server 2012上使用ServiceStack OrmLite創建非聚集索引

不幸的是,我沒有運氣強迫非序列ID的索引是非集羣的。使用下表模型:

[Alias("Players")] 
public class Player 
{ 
    [Index(Unique = true, NonClustered = true)] 
    public Guid Id { get; set; } 

    [Required] 
    [StringLength(128)] 
    public string Url { get; set; } 
} 

CreateTableIfNotExists<Player>()方法似乎忽略指示以創建非聚集索引,並且創建聚集酮代替(這將導致index fragmentation and poor performance):

enter image description here

我在這裏錯過了什麼?

注意:這是與OrmLite 4.0.52,使用SqlServer2012Dialect供應商。

回答

1

這是一個非標準的RDBMS功能(即大多數RDBMS不支持),您必須在OrmLite之外進行管理,例如:手動添加聚簇索引dropping the clustered index on the Primary Key

您也可以利用Post Custom SQL Hooks來做到這一點。

+0

感謝您的信息。由於這些屬性參數什麼都不做/無聲無息,爲什麼它們完全存在? – easuter

+0

@easuter'[Index]'屬性僅用於在其他非主鍵屬性上創建索引。主鍵上可以使用'[PrimaryKey]'和'[AutoIncrement]'屬性。 – mythz

+1

我明白這一點,但我沒有詢問關於創建主鍵的問題,我問爲什麼'[Index]'屬性的'NonClustered'參數簡單地失敗了,而不是例如引發'NotImplementedException'。爲什麼NonClustered和Clustered參數存在,如果他們沒有任何目的? – easuter

1

這可能會減輕您對非聚集索引的需求。

我使用了一個轉換器來獲取序列Guid的SQL Server喜歡它的聚簇索引中的新插入。

public class SequentialSqlServerGuidConverter : SqlServerGuidConverter 
{ 
    public override object ToDbValue(Type fieldType, object value) 
    { 
     if (value is Guid && value.Equals(Guid.Empty)) 
     { 
      var newGuid = SequentialGuidGenerator.NewSequentialGuid(SequentialGuidType.SequentialAtEnd); 
      return newGuid; 
     } 
     return base.ToDbValue(fieldType, value); 
    } 
} 

SequentialGuidGenerator代碼可以在這裏找到:http://www.codeproject.com/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database

它顯然有改變Guid.Empty的所有值到一個新的SequentialGuid的副作用。在實踐中,我們並沒有試圖找到等於Guid.Empty的行,所以這不是問題。

+0

謝謝,這是一個有趣的解決方案,我會記住測試未來的項目! – easuter

相關問題