繁体   English   中英

父 - 子关系 子 ID

[英]Parent - Child relation Child ID

我有以下课程

public class Order
{
    public int OrderID {get;set;}
    /*...
    Some other properties
    ...*/
    public ICollection<OrderDetail> Details {get;set;}
}

public class OrderDetail
{
    public int OrderID {get;set;}
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OrderDetailID {get;set;}
    /*...
    Some other properties
    ...*/

    public Order Order {get;set;}
}

我还在 OnModelCreation 中指定了关系,如下所示:

modelBuilder.Entity<OrderDetail>().HasKey(detail => new { detail.OrderID, detail.OrderDetailID});
modelBuilder.Entity<OrderDetail>().HasOne(detail => detail.Order)
                                            .WithMany(order => order.Details)
                                            .HasForeignKey(detail => detail.OrderID).OnDelete(DeleteBehavior.Cascade);

一切正常,没有任何错误。
我的问题是,在这种情况下,当我创建一个带有详细信息的订单时,所有详细信息的 OrderDetailID 都会增加,并且我在数据库中得到以下内容。

OrderID OrderDetailID ....     
17      19              3   15.0000 15.0000 EA      
17      20              3   15.0000 15.0000 EA     
18      21              1   25.0000 0.0000  EA     
18      22              1   25.0000 0.0000  EA

我了解 OrderDetailID 的工作方式与我代码中的配置相对应。 但是我的问题是我需要在数据库中得到如下图片:

OrderID OrderDetailID ....     
17      1               3   15.0000 15.0000 EA     
17      2               3   15.0000 15.0000 EA     
18      1               1   25.0000 0.0000  EA     
18      2               1   25.0000 0.0000  EA

换句话说,对于每个新订单,我都需要将 OrderDetailID 重置为 1。
我在实体框架中找不到任何配置选项来让它按照我需要的方式工作。

先感谢您。

您所期望的称为Identity column based on another column SQL Server 和 EF Core 都没有对此的默认支持。

你必须手动完成。 在 EF Core 中,您必须通过从数据库中获取此属性(列)的最大值,然后将其递增 1 来分配属性(列)值。

我想没有像 autoIncrementing Id 这样可以重置的东西,它看起来更像是您应该在代码中创建的行为,也许考虑使用Details列表中的索引作为 OrderDetailID

最好的是,如果您可以在插入时在数据库中创建触发器

它应该根据该特定订单的最高 ID 设置 orderDetailId

例子:

SELECT ISNULL(MAX(OrderDetailID)+1,1) FROM orderDetails WHERE orderID = inserted.OrderID

经过长时间的审查,我最终将以下脚本添加到迁移中。

migrationBuilder.Sql(@"CREATE OR ALTER TRIGGER [DetailLineNbr] ON Details AFTER INSERT AS 
                        BEGIN
                        declare @minLineNbr int;
                        declare @maxExistingLineNbr int;
                        SET @minLineNbr = (SELECT MIN(DetailID) FROM inserted);
                        SET @maxExistingLineNbr = ISNULL((SELECT MAX(LineNbr) FROM Details WHERE Details.OrderID in (select inserted.OrderID from inserted) AND Details.DetailID not in (select inserted.DetailID from inserted)),0);
                        UPDATE Details
                        SET LineNbr = Details.DetailID - @minLineNbr + @maxExistingLineNbr + 1
                        WHERE Details.OrderID in (select inserted.OrderID from inserted) AND Details.DetailID in (select inserted.DetailID from inserted) 
                        END");

David Edel 建议的解决方案仅适用于单行插入。 不幸的是,在我的情况下,几乎所有插入多行的插入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM