1

通过将聚合和值对象与 EF7 结合使用,我遇到了问题。

这是汇总:

public class MasterAgreement
{
    private string _name;

    public Guid Key { get; set; }
    public MasterAgreementRaise RegularRaise { get; private set; }
    public MasterAgreementRaise MarketRaise { get; private set; }

    protected MasterAgreement()
    { }

    public MasterAgreement(Guid key)
    {
        Key = key;
    }

    public MasterAgreement(Guid key, string name, MasterAgreementRaise regularRaise, MasterAgreementRaise marketRaise)
    {
        Key = key;
        _name = name;
        RegularRaise = regularRaise ?? throw new DomainException("Regular raise is missing");
        MarketRaise = marketRaise ?? throw new DomainException("Market raise is missing");
    }

    public void Update(MasterAgreement masterAgreement)
    {
        _name = masterAgreement._name;
        RegularRaise = masterAgreement.RegularRaise;
        MarketRaise = masterAgreement.MarketRaise;
    }
   }

这是值对象:

public class MasterAgreementRaise : ValueObject
{
    public int RaiseType { get; private set; }
    public int ConditionType { get; private set; }
    public decimal? Value { get; private set; }

    private MasterAgreementRaise() { }

    public MasterAgreementRaise(int raiseType, int conditionType, decimal? value)
    {
        RaiseType = raiseType;
        ConditionType = conditionType;
        Value = value;
    }

    protected override IEnumerable<object> GetAtomicValues()
    {
        // Using a yield return statement to return each element one at a time
        yield return RaiseType;
        yield return ConditionType;
        yield return Value;
    }
}

所以 MasterAgreement 包含 2 个公共 MasterAgreementRaise 字段

生成数据库的实体配置就是这样完成的,生成的数据库正确地符合 DDD 原则:

public class MasterAgreementTypeConfiguration : IEntityTypeConfiguration<MasterAgreement>
{
    public void Configure(EntityTypeBuilder<MasterAgreement> builder)
    {
        builder.HasKey(item => item.Key);

        builder.Property<Guid>("Key");
        builder.Property<string>("Name").IsRequired().HasMaxLength(250);

        builder.OwnsOne(item => item.RegularRaise);
        builder.OwnsOne(item => item.MarketRaise);
    }
}

尝试从数据库中更新或删除主协议时,EF7 无法处理此问题

更新期间的错误是:无法跟踪实体类型“MasterAgreement.RegularRaise#MasterAgreementRaise”的实例,因为已经在跟踪具有相同键值 {'MasterAgreementKey'} 的另一个实例。替换拥有实体时,修改属性而不更改实例或首先分离先前拥有的实体条目。

并且在删除过程中:“MasterAgreement”的实体与 MasterAgreement.RegularRaise#MasterAgreementRaise 共享表“MasterAgreement”,但没有具有相同键值的此类实体已标记为“已删除”

如何在不丢失值对象并通过添加标识符将其更改为实体的情况下解决此问题?

所有帮助将不胜感激

4

1 回答 1

0

目前不支持此 DDD 值对象方案,将从 EF Core 版本 2.1 开始提供地址。

您可以在此处关注相同的问题,该问题已通过更好的异常消息和此问题中版本 2.1 的最终解决方案得到解决

于 2018-03-13T10:03:12.730 回答