使用HiLo生成主键

2019-10-08 15:35 来源:未知

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实体,那么主键的值将从1000早先。

网络游戏新 6

同期由于IncrementBy选择设置为“5”,所以当在左右文中加多第6个插入时,将展开数据库调用以博得下三个类别值。以下是插入3个Category实体然后插入3个的Product实业时SQL Server profiler的荧屏截图,您能够见到数据库调用获取系列的下三个值的次数是2次。
网络游戏新 7

假设您对在Entity Framework Core中利用HiLo生成主键感兴趣,不防本身出手测验一下。

参谋资料:

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