使用HiLo生成主键

2019-10-12 12:18 来源:未知

HiLo是在NHibernate中生成主键的一种方法,然近年来后我们得以在Entity Framework Core中央银行使。所以在这里篇内容中,笔者将向你在介绍怎么样在Entity Framework Core中选用HiLo生成主键。

什么是Hilo?

HiLo是High Low的简写,翻译成汉语叫高低位方式。

HiLo是由“Hi”和“Lo”两有的生成主键的一种格局。“Hi”部分起点数据库,“Lo”部分在内存中生成以创办独一值。请牢记,“Lo”是一个范围数字,如0-100。因而,当“Hi”部分用完“Lo”范围时,再一次实行数据库调用以博取下一个“Hi数字”。故此HiLo情势的独到之处在于你事先能够通晓主键的值,而不用每一趟都与数库据发生互相

小结有以下四点:

  1. “Hi”部分由数据库分配,七个冒出央浼保管收获唯一的接连值;
  2. 设若获得“Hi”部分,我们还亟需通晓“incrementSize”的值(“Lo”条指标多寡);
    “Lo”取的界定:[0,incrementSize];
  3. 标志范围的公式是:(Hi - 1) * incrementSize) + 1(Hi - 1) * incrementSize) + incrementSize)
  4. 当有着“Lo”值使用完时,须要再行从数据库中抽出一个新的“Hi”值,并将“Lo”部分复位为0。

在那处演示在多个冒出事务中的例子,每一个业务插入八个实体:

图片 1

Sql Server 序列

在EF Core中运用HiLo生成主键,大家还亟需精晓Sql Server中二个概念序列(Sequence)

队列是在SQL Server 贰零壹叁中引进的(但是Oracle很已经已经落到实处了)。连串是客商定义的指标,它依照创制的属性生成一三种数值。它与 Identity 列相似,但它们之间有为数不菲不相同之处。举例,

  • 队列用于转移数据库范围的种类号;
  • 队列不与三个表相关联,您能够将其与多个表相关联;
  • 它能够用于插入语句来插入标志值,也能够在T-SQL脚本中采取。

成立体系示例的SQL语句:

Create Sequence [dbo].[Sequence_Test] 
As [BigInt]         --整数类型
Start With 1        --起始值
Increment By 1      --增量值
MinValue 1          --最小值
MaxValue 9999999    --最大值
Cycle               --达到最值循环 [ CYCLE | NO CYCLE ]
Cache  5;           --每次取出5个值缓存使用 [ CACHE [<常量>] | NO CACHE ]

选择示例:

Create Table #T(Id BigInt Primary Key,[Time] DateTime);

Insert Into #T
            ( Id , Time )
Values      ( NEXT VALUE FOR [dbo].[Sequence_Test] , -- Id - bigint
              GetDate()  -- Time - datetime
              )
Go 10


Select * From #T

询问结果:

Id Time
1 2017-11-23 16:46:50.613
2 2017-11-23 16:46:50.643
3 2017-11-23 16:46:50.667
4 2017-11-23 16:46:50.677
5 2017-11-23 16:46:50.687
6 2017-11-23 16:46:50.697
7 2017-11-23 16:46:50.707
8 2017-11-23 16:46:50.717
9 2017-11-23 16:46:50.730
10 2017-11-23 16:46:50.740

至于系列越来越多的内容,能够查阅如下材质:

动用HiLo生成主键

让我们看看如何使用HiLo在Entity Framework Core中生成主键。

为了演示,我们成立了八个尚未涉嫌的实体。

    public class Category
    {
        public int CategoryID { get; set; }
        public string CategoryName { get; set; }
    }

    public class Product
    {
        public int ProductID { get; set; }
        public string ProductName { get; set; }
    }

请记住,EF Core按老规矩配置一个名叫Id<type name>Id用作实体的主键属性。今后大家必要创立大家的DBContext,在这里边大家创立SampleDBContext.cs类:

public class SampleDBContext : DbContext
{
    public SampleDBContext()
    {
        Database.EnsureDeleted();
        Database.EnsureCreated();
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
    {
            var sqlConnectionStringBuilder = new SqlConnectionStringBuilder {
                DataSource = "****",
                InitialCatalog = "EFSampleDB",
                UserID = "sa",
                Password = "***"
            };
            optionsBuilder.UseSqlServer(sqlConnectionStringBuilder.ConnectionString);

    }

    protected override void OnModelCreating(ModelBuilder modelbuilder)
    {
        modelbuilder.ForSqlServerUseSequenceHiLo("DBSequenceHiLo");
    }

    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
}
  • SampleDBContext构造函数最初化数据库,类型于EF 6中的DropCreateDatabaseAlways
  • OnConfiguring() 方法用于配置数据库链接字符串;
  • OnModelCreating格局用于定义实人体模型型。要定义HiLo类别,请使用ForSqlServerUseSequenceHiLo扩张方法。您供给提供种类的称号。

运作应用程序,您应该在创建“EFSampleDB”数据库中看到Product表、Category表和DBSequenceHiLo序列。

图片 2

以下是创办DBSequenceHiLo的脚本。

Create Sequence [dbo].[DBSequenceHiLo] 
 As [BigInt]
 Start With 1
 Increment By 10
 MinValue -9223372036854775808
 MaxValue 9223372036854775807
 Cache 
Go

正如您所见到的,它从1起首,递增是10。

当今向数据库中增加一些数额。以下代码首先增多3个Category实业和调用SaveChanges(),然后增加3个Product实业并调用SaveChanges()

    using (var dataContext = new SampleDBContext())
    {
        dataContext.Categories.Add(new Category() { CategoryName = "Clothing" });
        dataContext.Categories.Add(new Category() { CategoryName = "Footwear" });
        dataContext.Categories.Add(new Category() { CategoryName = "Accessories" });
        dataContext.SaveChanges();
        dataContext.Products.Add(new Product() { ProductName = "TShirts" });
        dataContext.Products.Add(new Product() { ProductName = "Shirts" });
        dataContext.Products.Add(new Product() { ProductName = "Causal Shoes" });
        dataContext.SaveChanges();
    }

当以此代码第一遍被实施,Clothing 实体通过Add措施扩大到DBContext时,就能向数据库调用获取序列的值,大家也能够透过SQL Server Profiler来证明它。
图片 3

次调用dataContext.SaveChanges()时,3个Category实体将被封存。查看实行的SQL语句。主键值已经被变型,类别值的拿走也只举办了贰回。
图片 4

即便插入3个Product实业,体系值也不会从数据库中拿走。唯有当插入10条记下(Lo部分耗尽)时,才会向数据库调用得到下一个(Hi部分)体系值。

向HiLo运用到单个实体

地点的代码多少个表共用二个HiLo连串。即使你只想针对贰个特定的表,那么你能够接纳上面包车型客车代码。

    modelbuilder.Entity<Category>().
            Property(o => o.CategoryID).ForSqlServerUseSequenceHiLo();

这段代码将创立二个暗许名字为“EntityFrameworkHiLoSequence”的新连串,因为从没点名名字。您也足以定义三个HiLo类别。比如:

    protected override void OnModelCreating(ModelBuilder modelbuilder)
    {
        modelbuilder.ForSqlServerUseSequenceHiLo("DBSequenceHiLo");
        modelbuilder.Entity<Category>()
                .Property(o => o.CategoryID).ForSqlServerUseSequenceHiLo();
    }

在数据库中,将开创多个体系。Category实体将选取EntityFrameworkHiLoSequence序号,全数其余实体使用DBSequenceHiLo序列。

图片 5

配置HiLo序列

ForSqlServerHasSequence扩充方法不可能改变早先值和增量值的选项。不过,有一种方法来定义这么些采用。首先,使用HasSequence格局定义种类的StartAtIncrementBy选用,然后再选取ForSqlServerUseSequenceHiLo()恢宏方法,要保持类别的称呼一样。举例:

    modelbuilder.HasSequence<int>("DBSequenceHiLo")
                      .StartsAt(1000).IncrementsBy(5);
    modelbuilder.ForSqlServerUseSequenceHiLo("DBSequenceHiLo");

在此种情状下,生成DBSequenceHiLo的剧本如下。

CREATE SEQUENCE [dbo].[DBSequenceHiLo] 
 AS [int]
 START WITH 1000
 INCREMENT BY 5
 MINVALUE -2147483648
 MAXVALUE 2147483647
 CACHE 
GO

于是当大家实践同一的代码插入3个Category实业,那么主键的值将从一千开端。

图片 6

与此同一时间由于IncrementBy接纳设置为“5”,所以当在前后文中增添第6个插入时,将实行数据库调用以获得下二个种类值。以下是插入3个Category实体然后插入3个的Product实体时SQL Server profiler的显示器截图,您能够见到数据库调用获取种类的下三个值的次数是2次。
图片 7

尽管你对在Entity Framework Core中运用HiLo生成主键感兴趣,不防自个儿入手测量试验一下。

参考资料:

TAG标签:
版权声明:本文由澳门国际银河备用网址发布于网页测试游戏,转载请注明出处:使用HiLo生成主键