是否可以在 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.
}