我想使用客户端生成GUID而没有它在数据库端的碎片成本(我不想考虑在数据库端生成主键,因为我想利用DDD和单元测试)。
我正在使用SQL Server 2012和Entity Framework 6。
和实体
public partial class Mac { public Mac() { this.Id = Guid.NewGuid() } public System.Guid Id { get; set; } public string direccionMac { get; set; } }
所以,Id,非群集和主键。 MyClusterKey,聚簇索引,标识(1,1)
实体:
public partial class Mac
{
public Mac()
{
this.Id = Guid.NewGuid();
}
public System.Guid Id { get; set; }
public long MyClusterKey { get; set; }
public string direccionMac { get; set; }
}
MyClusteredKey已添加为DatabaseGeneratedOption.Identity:
public class MacMap : EntityTypeConfiguration<Mac>
{
public MacMap()
{
// Primary Key
this.HasKey(t => t.Id);
// Properties
this.Property(t => t.MyClusterKey)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(t => t.direccionMac)
.IsRequired()
.IsFixedLength()
.HasMaxLength(16);
// Table & Column Mappings
this.ToTable("Macs");
this.Property(t => t.Id).HasColumnName("Id");
this.Property(t => t.MyClusterKey).HasColumnName("MyClusterKey");
this.Property(t => t.direccionMac).HasColumnName("direccionMac");
}
}
这将按某种顺序生成Guids:
问题:
答案 0 :(得分:0)
我会选择选项2,因为你会理解它背后的逻辑,但是没有任何意义,因为无论如何都会有碎片。即便如此,性能下降也会相同甚至最差,因为应该在客户端进行更多的工作流程来组织它,就像在opt 2中一样,因为顺序逻辑不适用于场景中的页面。同样,我宁愿选择第二种选择,但它还取决于表格的消费或服务方式以及您尝试从中获取的内容。让我更深入地了解一下,如果你在threadlocal上共享一个上下文,顺序id应该是明确的方法,因为你可以控制创建的下一个键(因此opt3将是你的候选者),你将避免表碎片。但是,在某些情况下,最好不要控制EF中的线程安全性,让对象上下文处理它在任何情况下进入db的方式。对于这种情况,您将对数据库进行两次往返,因为只需要控制一个常规身份密钥来确认您获得的内容。但是如果你必须控制线程,那么选择3是要走的路,虽然你不会摆脱表碎片(至少从某些角度看其他来源)但你可以重用其他变量(在多个上下文wcf后面实现更高的吞吐量) 。在任何情况下,opt 2最适合于几种场景,这些场景将实现您希望在构建解决方案时实现的平衡。