Entity Framework Core 使用HiLo生成主键。Entity Framework Core 1.1 Preview 1 简介。

HiLo是以NHibernate中生成主键的一致种植方法,不过本咱们可以于Entity
Framework Core中动用。所以当当下篇内容遭,我以朝着您当介绍如何以Entity
Framework Core中使用HiLo生成主键。

实体框架核心(EF Core)是Entity
Framework的一个轻量级,可扩大及跨平台版本。 10月25日,Entity Framework
Core 1.1 Preview 1发布了。

什么是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

升级到Entity Framework Core 1.1 Preview 1

假如你使用由EF团队(SQL
Server,SQLite和InMemory)提供的数据库提供程序之一,则只待升级提供程序包。

PM> Update-Package Microsoft.EntityFrameworkCore.SqlServer –Pre
如果您使用的是第三方数据库提供程序,请检查它们是否已发布依赖于1.1.0-preview1-final的更新。 如果他们有,那么只是升级到新版本。 如果没有,那么你应该只能升级它们依赖的EF Core关系组件。 1.1中的大部分新功能不需要更改数据库提供程序。 EF开发组做了一些测试,以确保依赖于1.0的数据库提供程序继续使用1.1预览1,但这个测试还不详尽。

 
PM> Update-Package Microsoft.EntityFrameworkCore.Relational –Pre

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脚论中采取。

创立行示例的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

有关序列更多之情节,可以查看如下材料:

  • 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/

升级tooling packages

倘你以的家伙确保,那么必然要是升级。
请注意,工具版本化为1.0.0-preview3-final,因为工具没有达成其开稳定版本(在.NET
Core,ASP.NET Core和EF Core上之家伙都是这样)。

PM> Update-Package Microsoft.EntityFrameworkCore.Tools –Pre
如果您使用的是ASP.NET Core,那么您需要更新project.json的tools部分以使用新的Microsoft.EntityFrameworkCore.Tools.DotNet包。 随着.NET CLI工具的设计的进行,我们必须将dotnet ef工具分离到这个单独的包中。
"tools": {
  "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-preview3-final"
},

动用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部分)序列值。

什么是Entity Framework Core 1.1 Preview 1

1.1版本专注让解决阻碍人们用EF Core的题目。
这包括修复错误并累加一些无在EF Core中贯彻之显要功能。
虽然EF开发组在这地方获取了部分帅的拓展,但是,EF
Core仍然未会见是每个人的不易抉择。 有关落实之再多详细信息,请参见下面的EF
Core和EF6.x比较。

朝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

EF Core和EF6.x比较

起个别单版的Entity Framework,Entity Framework Core和Entity Framework
6.x.

配置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生成主键感兴趣,不防自己动手测试一下。

参考资料:

  • https://vladmihalcea.com/2014/06/23/the-hilo-algorithm/
  • http://www.talkingdotnet.com/use-hilo-to-generate-keys-with-entity-framework-core/

Entity Framework 6.x

Entity Framework
6.x(EF6.x)是一模一样栽经过试验与测试的数目访问技术,具有多年之效用以及稳定性。
它首赖在2008年颁发,作为.NET Framework 3.5 SP1和Visual Studio 2008
SP1的同一组成部分。 从EF4.1版本开始,它看做EntityFramework NuGet包发运 –
目前是NuGet.org上顶受欢迎之包。

EF6.x继续是一个被支持的活,并拿继续拓展不当修复及多少的改善。

Entity Framework Core

实业框架核心(EF Core)是Entity
Framework的一个轻量级,可扩大及跨平台版本。 与EF6.x相比,EF
Core引入了累累更上一层楼与初职能。 同时,EF Core 是一个初的代码基础

EF Core保留了自EF6.x的开发者体验,大多数五星级API也保持不更换,因此EF
Core对采用EF6.x的用户会觉得格外熟悉。 同时,EF
Core构建了一样学新的骨干零部件。 这象征EF
Core不见面自动继承EF6.x的具备力量。
其中有的效以在未来版本中显得(例如延迟加载与连续弹性),其他较无常用的功力以非会见于EF
Core中贯彻。

初的,可扩大的以及轻量级核心还允许我们当EF核心中上加有于EF6.x中不可知兑现之特征(例如当LINQ查询中的备用密钥和混客户端/数据库评估)。

改进LINQ翻译

以1.1本中,EF研发团队于改善EF Core LINQ提供次方面得到了好的进行。
这让再多的查询能够得逞施行,在数据库(而非是内存)中评估更多之逻辑。

DbSet.Find

DbSet.Find(…)是一个存于EF6.x被之API,并且是EF
Core的重复广阔的乞求之一。 它同意你根据主键值轻松查询实体。
如果实体已经加载到上下文中,则回她使未查询数据库。

using (var db = new BloggingContext())
{
    var blog = db.Blogs.Find(1);
}

投到字段(Mapping to fields)

API中的新的HasField(…)方法允许你为性配置备用字段。
这是极度广大的做法是当一个属性没有setter。

public class BloggingContext : DbContext
{
    ...

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.Property(b => b.Url)
.HasField(“_theUrl”);
}
}

默认情况下,EF将在查询期间构造实体的实例时使用该字段,或者当它无法使用该属性时(即,它需要设置值,但没有属性设置器)。 您可以通过新的UsePropertyAccessMode(...)API更改。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .HasField("_theUrl")
        .UsePropertyAccessMode(PropertyAccessMode.Field);
}

乃还得在模型中创造以实业类中从不对号入座属性的属性,但使用字段将数据存储在实业中。
这同“阴影属性”(下面介绍,距离这里12cm)不同,数据存储在反跟踪器中。
如果实体类应用办法来赢得/设置值,则一般采取这个方法。

而可当性质(…)API中为EF字段的称呼。
如果无兼具给定名称的性质,则EF将追寻一个字段。

public class BloggingContext : DbContext
{
    ...

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.Property(“_theUrl”);
}
}

您还可以选择为该属性指定名称,而不是字段名称。 然后在创建模型时使用此名称,最明显的是它将用于映射到数据库中的列名称。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property<string>("Url")
        .HasField("_theUrl");
}
您可以使用EF.Property(...)方法在LINQ查询中引用这些属性。
var blogs = db.Blogs
    .OrderBy(b => EF.Property<string>(b, "Url"))
    .ToList();
 

黑影属性(Entity Framework Core)

影子属性是实体类吃莫存在的性。
这些性的价与状态了保存在改动跟踪器中

足由此ChangeTracker API获取和转阴影属性值。

context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;
阴影属性可以通过EF.Property静态方法在LINQ查询中引用。
var blogs = context.Blogs
    .OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));

黑影属性约定(Conventions Shadow Properties)

遵照惯例,仅当发现涉嫌时才创建阴影属性,但当专属实体类吃寻找不顶外键属性。
在这种状况下,将引入影子外键属性。
shadow外键属性将命名为<navigation property name><principal
key property
name>
(在借助实体上之导航,它对主体实体,用于命名)。
如果主键属性名称包含导航属性的号,则名将只是<principal key
property name>

如果由属于实体上未曾导航属性,则以该职务应用主类型名称。

比如,以下代码清单将招致向Post实体引入BlogId shadow属性。

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

阴影属性数据注释

束手无策以数据注释创建阴影属性。

阴影属性Fluent API

汝可以使用Fluent API配置阴影属性。
一旦您调用了Property的字符串重载,你就可以链接任何针对另属性之安排调用。

苟提供给Property方法的名号与现有属性(阴影属性或实体类及定义之性)的称匹配,则代码用部署现有属性,而非是引入新的shadow属性。

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property<DateTime>("LastUpdated");
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

影子属性介绍完!

 

显式加载

显式加载允许你加载由上下文跟踪的实业的导航属性的内容。

using (var db = new BloggingContext())
{
    var blog = db.Blogs.Find(1);

db.Entry(blog).Collection(b => b.Posts).Load();
db.Entry(blog).Reference(b => b.Author).Load();
}

来自EF6.x的其他EntityEntry API

EF研发集团上加了EF6.x中提供的其余EntityEntry API。
这包Reload(),GetModifiedProperties(),GetDatabaseValues()等。这些API最常用之凡通过调用DbContext.Entry(对象实体)方法。

连年弹性

一连弹性自动重试失败的数据库命令。 此版本包括占为SQL Server(包括SQL
Azure)定制的尽策略。 此执行策略包含在我们的SQL Server提供次中。
它知道得重试的不得了类型,并且有明显的默认值,用于最要命重试次数,重试之间的缓等。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer(
        "<connection string>",
        options => options.EnableRetryOnFailure());
}

外数据库提供者可以择丰富为那个数据库定制的重试策略。
还产生同等栽体制来注册自己之自定义执行策略。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseMyProvider(
        "<connection string>",
        options => options.ExecutionStrategy(...));
}

 

SQL Server内存优化表支持

内存优化表是SQL Server的同等宗功能。
您现在可指定实体映射到之表明是内存优化的。 当使用EF
Core基于您的模子(使用迁移或Database.EnsureCreated)创建及保安数据库时,将为这些实体创建一个内存优化表。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .ForSqlServerIsMemoryOptimized();
 }
 

简化服务转移

于EF Core
1.0蒙受,可以替换EF使用的中间服务,但随即是纵横交错的,需要你控制EF使用的倚重注入容器。
在1.1吃,我们用了一个ReplaceService(…)方法,可以在配备上下文时使用她。

public class BloggingContext : DbContext
{
    ...

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{


optionsBuilder.ReplaceService();
}
}

Entity Framework Core 1.1 Preview 1的前程版本

安静的1.1本子将给当年晚些时候推出。
EF研发团队不计划以preview1和平稳版本中添加其它新效能。
将只是努力修复报告的缪。

EF研发集团现在用注意力转移到EF Core 1.2和EF6.2版。
将以抢底将来享受这些本子的详细信息。

 

贴平摆Rowan
Miller的帅照。Microsoft员工,EF研发团队成员,他的个人Blog:https://romiller.com/,有趣味的情人可错过探访。

图片 8

最终,希望本文对您持有助。

转载请注明出处,转载请注明出处,转载请注明出处,重要的业务说其三全副:http://www.cnblogs.com/smallprogram/

admin

网站地图xml地图