自动递增编号 EF Core 的最佳实践

Est*_*net 3 c# automapper entity-framework-core asp.net-core

我正在寻找最佳实践,以便使用 EF Core 增加数据库中的一些数字。

我有一个名为 PARENT 的数据库模型。在我的申请中,我可以有多个父母。每个父母都有几个孩子。

父级 1:子级 1 - 子级 2

父级 2:子级 1 - 子级 2 - 子级 3

我希望,在每个 PARENT 内部,每个孩子都按一列递增编号:int Number。这意味着,

父1.子1 = 001;

父1.子2 = 002;

父2.子1 = 001;

父2.子2 = 002;

...

因此,它必须是唯一的并且由父级递增。

谁能给我一些最佳实践,以便以有效的方式实现这一目标?

更新

public class Bar {
    public Guid BarId {get;set;}
    public ICollection<Client> Clients {get;set;}
}

public class Client {
    public Guid ClientId {get;set;}
    public Guid BarId {get;set;}
    public int ClientNumber {get;set;}
}

public class Context : DBContext {
    entity.HasKey(e => new { e.BarId, e.ClientId }).HasName("PK_CLIENT");
                entity.Property(e => e.ClientId).ValueGeneratedWhenDefault();
    entity.Property(e => e.ClientNumber).ValueGeneratedOnAdd();
    entity.HasIndex(e => new {e.BarId, e.ClientNumber}).IsUnique()
        .HasName("IX_CLIENT_NUMBER");
}
Run Code Online (Sandbox Code Playgroud)

通过调用,ValueGeneratedOnAdd()我使数字列递增,但我希望它为每个栏递增,因此它应该允许不同栏之间重复的客户编号,但不能在同一个栏上,并且还按栏递增它们,而不仅仅是按客户实体递增。

joa*_*del 5

一种方法是执行以下操作;

1) 使用整数作为键,并将 ClientNumber 属性设置为可为空。

    public class Bar
    {
        public int BarId { get; set; }
        public ICollection<Client> Clients { get; set; }
    }

    public class Client
    {
        public int ClientId { get; set; }
        public Bar Bar { get; set; }
        public int BarId { get; set; }
        public int? ClientNumber { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

2)将ClientId设置为identity(自动递增),并将ClientNumber设置为数据库生成的(否则EF Core在插入后不会重新从数据库读取值)

entity.Property(e => e.ClientId).ValueGeneratedOnAdd();
entity.Property(e => e.ClientNumber).ValueGeneratedOnAddOrUpdate();
Run Code Online (Sandbox Code Playgroud)

3)添加触发器,用于在插入后修改ClientNumber

    public class Bar
    {
        public int BarId { get; set; }
        public ICollection<Client> Clients { get; set; }
    }

    public class Client
    {
        public int ClientId { get; set; }
        public Bar Bar { get; set; }
        public int BarId { get; set; }
        public int? ClientNumber { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

现在,所有插入操作都会自动进行:

            var bar1 = new Bar() { Clients = new List<Client>() };
            var bar2 = new Bar() { Clients = new List<Client>() };

            bar1.Clients.Add(new Client());
            bar1.Clients.Add(new Client());

            bar2.Clients.Add(new Client());
            bar2.Clients.Add(new Client());

            context.Bars.AddRange(new[] { bar1, bar2 });
            await context.SaveChangesAsync();

            bar1.Clients.Add(new Client());
            bar2.Clients.Add(new Client());
            bar1.Clients.Add(new Client());
            await context.SaveChangesAsync();
Run Code Online (Sandbox Code Playgroud)

将会渲染

ClientId    BarId   ClientNumber
1   1   1
2   1   2
6   1   3
7   1   4
3   2   1
4   2   2
5   2   3
Run Code Online (Sandbox Code Playgroud)

缺点是您不能使用唯一索引 IX_CLIENT_NUMBER,因为在触发器执行之前 ClientNumber 将为 NULL。