2016-01-20 72 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

相关问题