最新1000套html5模版论坛(html 论坛)

原文链接:http://www.cnblogs.com/tdfblog/archive/2017/11/23/entity-framework-core-hilo.html

作者:Sweet Tang

HiLo是在NHiernate中生成主键的一种方式,不过现在我们可以在Entity Framework Core中使用。所以在这篇内容中,我将向您在如何使用HiL在Entity Framework Core生成主键。

什么是Hilo?

HiLo是High Low的简写,翻译中文叫高低位模式。

最新1000套html5模版论坛(html 论坛)

HiLo是主键由“Hi”和“Lo”两部分组成的模式。“Hi”部分来自数据库,“Lo”部分在内存中生成以创建唯一值。请记住,“Lo”是一个范围数字,如0-100。因此,当“Hi”数字用完“Lo”范围时,再次进行数据库调用以获得下一个“Hi数字”。所以HiLo模式的优点在于您预先知道主键的值,而不用每次都与数据发生交互。

“Hi”部分由数据库分配,两个并发请求保证得到唯一的连续值;

一旦获取“Hi”部分,我们还需要知道“incrementSize”的值(“Lo”条目的数量);

“Lo”取的范围:[0,incrementSize];

标识范围的公式是:(Hi - 1) * incrementSize) + 1到 (Hi - 1) * incrementSize) + incrementSize)

当所有“Lo”值使用完时,需要重新从数据库中取出一个新的“Hi”值。

在这里演示两个并发事务的例子,每个事务插入多个实体:

Sql Server 序列

在EF Core中使用HiLo生成主键,我们还需要了解Sql Server中一个概念序列(Sequence)。

序列是在SQL Server 2012中引入的(不过Oracle很早就已经实现了http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_6015.htm)。序列是用户定义的对象,它根据创建的属性生成一系列数值。它与 Identity 列相似,但它们之间有很多不同之处。例如,

序列用于生成数据库范围的序列号;

序列不与一个表相关联,您可以将其与多个表相关联;

它可以用于插入语句来插入标识值,也可以在T-SQL脚本中使用。

创建的Sequence的示例SQL语句:

CreateSequence[dbo].[Sequence_Test] As[ BigInt] --整数类型StartWith1--起始值IncrementBy1--增量值MinValue1--最小值MaxValue9999999--最大值Cycle--达到最值循环 [ CYCLE | NO CYCLE ]Cache5; --每次取出5个值缓存使用 [ CACHE [<常量>] | NO CACHE ]

使用示例:

CreateTable# T( IdBigIntPrimaryKey,[ Time] DateTime); InsertInto# T( Id, Time) Values( NEXTVALUEFOR[dbo].[Sequence_Test] , -- Id - bigintGetDate() -- Time - datetime) Go10Select* 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

关于序列更多的内容,可以查阅如下资料:

http://www.cnblogs.com/CareySon/archive/2012/03/12/2391581.html

http://www.cnblogs.com/dotnet261010/p/7082852.html

http://sqlhints.com/2015/08/01/difference-between-sequence-and-identity-in-sql-server/

https://raresql.com/2012/05/01/difference-between-identity-and-sequence/

使用HiLo生成主键

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

为了演示,我们创建了两个没有关系的实体。

publicclassCategory{ publicintCategoryID { get; set; } publicstringCategoryName { get; set; } } publicclassProduct{ publicintProductID { get; set; } publicstringProductName { get; set; } }

请记住,EF Core按惯例配置一个名为Id或Id作为实体的主键属性。现在我们需要创建我们的DBContext,在这里我们创建SampleDBContext.cs类:

publicclassSampleDBContext: DbContext{ publicSampleDBContext() { Database.EnsureDeleted(); Database.EnsureCreated(); } protectedoverridevoidOnConfiguring(DbContextOptionsBuilder optionbuilder) { varsqlConnectionStringBuilder = newSqlConnectionStringBuilder { DataSource = "****", InitialCatalog = "EFSampleDB", UserID = "sa", Password = "***"}; optionsBuilder.UseSqlServer(sqlConnectionStringBuilder.ConnectionString); } protectedoverridevoidOnModelCreating(ModelBuilder modelbuilder) { modelbuilder.ForSqlServerUseSequenceHiLo( "DBSequenceHiLo"); } publicDbSet<Product> Products { get; set; } publicDbSet<Category> Categories { get; set; }}

在SampleDBContext构造函数初始化数据库,类型于EF 6中的DropCreateDatabaseAlways;

OnConfiguring() 方法用于配置数据库链接字符串;

OnModelCreating方法用于定义实体模型。要定义HiLo序列,请使用ForSqlServerUseSequenceHiLo扩展方法。您需要提供序列的名称。

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

以下是创建DBSequenceHiLo的脚本。

CreateSequence[dbo].[DBSequenceHiLo] As[ BigInt] StartWith1IncrementBy10MinValue-9223372036854775808MaxValue9223372036854775807CacheGo

正如你所看到的,它从1开始,递增是10。

Category实体和调用SaveChanges(),然后添加3个Product实现并调用SaveChanges()。

using( vardataContext = newSampleDBContext()) { dataContext.Categories.Add( newCategory() { CategoryName = "Clothing"}); dataContext.Categories.Add( newCategory() { CategoryName = "Footwear"}); dataContext.Categories.Add( newCategory() { CategoryName = "Accessories"}); dataContext.SaveChanges(); dataContext.Products.Add( newProduct() { ProductName = "TShirts"}); dataContext.Products.Add( newProduct() { ProductName = "Shirts"}); dataContext.Products.Add( newProduct() { ProductName = "Causal Shoes"}); dataContext.SaveChanges(); }

当这个代码第一次被执行,Clothing 实体通过Add方法增加到DBContext时,就会向数据库调用获取序列的值,我们也可以通过SQL Server Profiler来验证它。

次调用dataContext.SaveChanges()时,3个Category实体将被保存。查看执行的SQL语句。主键值已经被生成,序列值的获取也只执行了一次。

即使插入3个Product实体,序列值也不会从数据库中获取。只有当插入10条记录(Lo部分耗尽)时,才会向数据库调用获得下一个(Hi部分)序列值。

向HiLo运用到单个实体

上面的代码两个表共用一个HiLo序列。如果您只想针对一个特定的表,那么您可以使用下面的代码。

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

这段代码将创建一个默认名称为“EntityFrameworkHiLoSequence”的新序列,因为没有指定名字。您也可以定义多个HiLo序列。例如:

protectedoverridevoidOnModelCreating(ModelBuilder modelbuilder) { modelbuilder.ForSqlServerUseSequenceHiLo( "DBSequenceHiLo"); modelbuilder.Entity<Category>() .Property(o => o.CategoryID).ForSqlServerUseSequenceHiLo(); }

在数据库中,将创建两个序列。Category实体将使用EntityFrameworkHiLoSequence序号,所有其它实体使用DBSequenceHiLo序列。

配置HiLo序列

ForSqlServerHasSequence扩展方法不能更改起始值和增量值的选项。但是,有一种方法来定义这些选项。首先,使用HasSequence方法定义序号的StartAt和IncrementBy选项,然后再使用ForSqlServerUseSequenceHiLo()扩展方法,要保持序列的名称一致。例如:

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

在这种情况下,生成DBSequenceHiLo的脚本如下。

CREATESEQUENCE[dbo].[DBSequenceHiLo] AS[ int] STARTWITH1000INCREMENTBY5MINVALUE-2147483648MAXVALUE2147483647CACHEGO

所以当我们执行相同的代码插入3个Category实体,那么主键的值将从1000开始。

duct`实体时SQL Server profiler的屏幕截图,您可以看到数据库调用获取序列的下一个值的次数是2次。

1、本网站名称:源码村资源网
2、本站永久网址:https://www.yuanmacun.com
3、本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
4、本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
6、本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
源码村资源网 » 最新1000套html5模版论坛(html 论坛)

1 评论

您需要 登录账户 后才能发表评论

发表评论

欢迎 访客 发表评论