是否可以在 EntityFramework 6 中以特定步长自动递增 ID?
Is it possible to autoincrement an ID with a certain step size in EntityFramework 6?
我需要从 100'000 开始我的模型 ID,并为每个后续项目将其递增 100'000。有没有办法在 EF6 中执行此操作?我已经在寻找 Annotations 和 Fluent API 解决方案,但找不到任何东西。
我只在 EF Core 中找到了一种方法,但在 EF 6 中似乎没有类似的方法 (https://docs.microsoft.com/en-us/ef/core/modeling/relational/sequences)
当前型号:
public class Bubble
{
// Keys
[Required]
[Key]
public Int64 BubbleId { get; set; }
// Members (needs max. string length that you can set it to unique ->
[Required]
[StringLength(450)]
[Index(IsUnique = true)]
public string BubbleName { get; set; }
// Navigation propertys
public virtual ICollection<BubbleNode> BubbleNodes { get; set; }
}
如果您从新模式开始,则可以拦截模式创建并更改身份创建。如果模式已经创建(即依靠迁移)则不是这样。 SQL 例如将允许重新播种身份,但不会更改增量。
此示例使用名为 [Somethings] 的 table 并检查何时创建 table,如果找到则用 IDENTITY(100000,100000) 替换 "IDENTITY"。不幸的是,据我对 EF 6 的了解,拦截器不能从上下文中 attached/detached,因此您可以使用标志来确保拦截器 check/replace 代码不会一直 运行默认。
拦截架构创建:
public class Interceptor : IDbCommandInterceptor
{
void IDbCommandInterceptor.NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{ }
void IDbCommandInterceptor.NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
if (interceptionContext.DbContexts.OfType<SomethingDbContext>().Any(x => !x.ShouldIntercept))
return;
var regex = "NOT NULL IDENTITY,";
var replacement = "NOT NULL IDENTITY(100000,100000),";
if (command.CommandText.StartsWith("CREATE TABLE [dbo].[Somethings]"))
command.CommandText = Regex.Replace(command.CommandText, regex, replacement);
}
void IDbCommandInterceptor.ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{ }
void IDbCommandInterceptor.ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{ }
void IDbCommandInterceptor.ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{ }
void IDbCommandInterceptor.ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{ }
}
public class SomethingConfiguration : DbConfiguration
{
public SomethingConfiguration()
{
AddInterceptor(new Interceptor());
}
}
然后在您的 DbContext 中:
[DbConfigurationType(typeof(SomethingConfiguration))]
public class SomethingDbContext : DbContext
{
public bool ShouldIntercept { get; set;} = false;
// .. DbSets, etc.
}
默认情况下,您的 DbContext 不会主动拦截命令命令,因为我们真的只想激活此开销检查一次。当您的应用程序启动时,您可以初始化 DbContext,将 ShouldIntercept 设置为 True,然后执行一个简单的查询以确保 DbContext 架构 inspection/creation 运行s:
using (var context = new SomethingDbContext())
{
context.ShouldIntercept = true;
var test = context.Somethings.Any(); // Triggers schema check/creation.
}
我需要从 100'000 开始我的模型 ID,并为每个后续项目将其递增 100'000。有没有办法在 EF6 中执行此操作?我已经在寻找 Annotations 和 Fluent API 解决方案,但找不到任何东西。
我只在 EF Core 中找到了一种方法,但在 EF 6 中似乎没有类似的方法 (https://docs.microsoft.com/en-us/ef/core/modeling/relational/sequences)
当前型号:
public class Bubble
{
// Keys
[Required]
[Key]
public Int64 BubbleId { get; set; }
// Members (needs max. string length that you can set it to unique ->
[Required]
[StringLength(450)]
[Index(IsUnique = true)]
public string BubbleName { get; set; }
// Navigation propertys
public virtual ICollection<BubbleNode> BubbleNodes { get; set; }
}
如果您从新模式开始,则可以拦截模式创建并更改身份创建。如果模式已经创建(即依靠迁移)则不是这样。 SQL 例如将允许重新播种身份,但不会更改增量。
此示例使用名为 [Somethings] 的 table 并检查何时创建 table,如果找到则用 IDENTITY(100000,100000) 替换 "IDENTITY"。不幸的是,据我对 EF 6 的了解,拦截器不能从上下文中 attached/detached,因此您可以使用标志来确保拦截器 check/replace 代码不会一直 运行默认。
拦截架构创建:
public class Interceptor : IDbCommandInterceptor
{
void IDbCommandInterceptor.NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{ }
void IDbCommandInterceptor.NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
if (interceptionContext.DbContexts.OfType<SomethingDbContext>().Any(x => !x.ShouldIntercept))
return;
var regex = "NOT NULL IDENTITY,";
var replacement = "NOT NULL IDENTITY(100000,100000),";
if (command.CommandText.StartsWith("CREATE TABLE [dbo].[Somethings]"))
command.CommandText = Regex.Replace(command.CommandText, regex, replacement);
}
void IDbCommandInterceptor.ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{ }
void IDbCommandInterceptor.ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{ }
void IDbCommandInterceptor.ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{ }
void IDbCommandInterceptor.ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{ }
}
public class SomethingConfiguration : DbConfiguration
{
public SomethingConfiguration()
{
AddInterceptor(new Interceptor());
}
}
然后在您的 DbContext 中:
[DbConfigurationType(typeof(SomethingConfiguration))]
public class SomethingDbContext : DbContext
{
public bool ShouldIntercept { get; set;} = false;
// .. DbSets, etc.
}
默认情况下,您的 DbContext 不会主动拦截命令命令,因为我们真的只想激活此开销检查一次。当您的应用程序启动时,您可以初始化 DbContext,将 ShouldIntercept 设置为 True,然后执行一个简单的查询以确保 DbContext 架构 inspection/creation 运行s:
using (var context = new SomethingDbContext())
{
context.ShouldIntercept = true;
var test = context.Somethings.Any(); // Triggers schema check/creation.
}