1

我正在使用 DDD 构建一个项目。因此,更新/添加/删除子实体的唯一方法是通过其父实体,当我使用 dotnet core 2.0 时这不是问题,但现在我将项目迁移到 dotnet core 3.1 我收到以下错误:

数据库操作预计会影响 1 行,但实际上会影响 0 行。自加载实体以来,数据可能已被修改或删除。有关了解和处理乐观并发异常的信息,请参阅http://go.microsoft.com/fwlink/?LinkId=527962

我有一个这样的客户端类:

public class Client
{
    /// <summary>
    /// DDD Patterns comment Using a private collection field, better for DDD Aggregate's
    /// encapsulation so Receptions cannot be added from "outside the AggregateRoot" directly to
    /// the collection, but only through the method ClientAggrergateRoot.AddReception() which
    /// includes behaviour.
    /// </summary>
    private readonly List<Reception> _receptions;

    public Client(Guid id, string name, string url, string domainEmail)
    {
        Id = id;
        Name = name;
        Url = url;
        DomainEmail = domainEmail;
        _receptions = new List<Reception>();
    }

    protected Client()
    {
        _receptions = new List<Reception>();
    }

    public string Name { get; private set; }

    public string Url { get; private set; }

    public string DomainEmail { get; private set; }

    public bool IsDeleted { get; private set; }

    public DateTime CreatedAt { get; private set; }

    public DateTime ModifiedAt { get; private set; }

    public IReadOnlyCollection<Reception> Receptions => _receptions;        
}

我有我的接待课:

public class Reception
{
    public Reception(Guid id, string name, string address, string noteToGuest, string noteToReceptionst,
        string timeZone, Guid clientId)
    {
        Id = id;
        Name = name;
        Address = address;
        ClientId = clientId;
    }

    private Reception()
    {
    }

    public Guid ClientId { get; private set; }

    public string Name { get; private set; }

    public string Address { get; private set; }        
}

这是客户端配置文件:

public class ClientEntityTypeConfiguration
    : IEntityTypeConfiguration<Client>
{
    public void Configure(EntityTypeBuilder<Client> builder)
    {
        builder.ToTable("Clients", BeWelcomeContext.CLIENT_SCHEMA);
        builder.HasKey(c => c.Id);            

        var navigation = builder.Metadata.FindNavigation(nameof(Client.Receptions));

        // DDD Patterns comment: Set as field (New since EF 1.1) to acces the Receptions
        // collection property through its fields
        navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
    }
}

以及接收配置文件:

public class ReceptionEntityTypeConfiguration
    : IEntityTypeConfiguration<Reception>
{
    public void Configure(EntityTypeBuilder<Reception> builder)
    {
        builder.ToTable("Receptions", BeWelcomeContext.CLIENT_SCHEMA);
        builder.HasKey(r => r.Id);

        builder.HasOne<Client>()
            .WithMany(r => r.Receptions)
            .IsRequired()
            .HasForeignKey(r => r.ClientId);
    }
}

在我进行项目迁移之前,这一直很有效,如果我必须更改某些配置,我不知道发生了什么。

4

2 回答 2

2

https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/break-changes#detectchanges-honors-store-generated-key-values

这是 dot net 3.0 中的一个重大变化。

如果您正在使用 Guid 键并预生成它们(我正在做相同的 DDD 工作),那么 Ef 现在将其视为修改后的对象而不是新对象。

解决方案是关闭模型的密钥生成。

上面的链接有详细的解释。但总而言之,您需要在 DbContext 中进行此更改OnModelCreating

modelBuilder
.Entity<Client>()
.Property(e => e.Id)
.ValueGeneratedNever();

如果模型是从具有 Id 属性的某个类(如 Entity)派生的,则可能使用更好的解决方法,

 [DatabaseGenerated(DatabaseGeneratedOption.None)]
 public string Id { get; set; }

在父级上设置它会将其应用于所有类。

于 2020-06-16T22:58:19.810 回答
0

数据库操作预计会影响 1 行,但实际上会影响 0 行。自加载实体以来,数据可能已被修改或删除。有关了解和处理乐观并发异常的信息,请参阅http://go.microsoft.com/fwlink/?LinkId=527962

您的数据库似乎阻止修改数据。看看你的日志,复制 EF Core 创建的 SQL 查询并尝试在你的 DBMS 中运行它,也许你会得到更详细的错误。通常会有一个触发器阻止执行该操作。

于 2020-01-06T14:58:27.183 回答