【问题标题】:Adding Value Object to EF Entity - The entity type cannot be configured as owned because it has already been configured as a non-owned将值对象添加到 EF 实体 - 实体类型无法配置为拥有,因为它已配置为非拥有
【发布时间】:2022-08-17 00:15:18
【问题描述】:

我们收到以下错误,这似乎仅在将日期时间添加到值对象时发生。 \'实体类型 \'TimeWindow\' 无法配置为拥有,因为它已被配置为非拥有。如果你想覆盖以前的配置,首先通过调用\'Ignore\'从模型中删除实体类型。

值对象类:

public class TimeWindow : ValueObject
    {
        public DateTime? StartTime { get; set; }
        public DateTime? EndTime { get; set; }

        private TimeWindow()
        {
        }

        public TimeWindow(
            DateTime? startTime,
            DateTime? endTime)
        {
            StartTime = startTime;
            EndTime = endTime;
        }

        protected override IEnumerable<object> GetAtomicValues()
        {
            yield return StartTime;
            yield return EndTime;
        }
    }

在 OnModelCreating 内部,我们添加了一个 OwnsOne 关系:

builder.Entity<Manifest>(b =>
        {
            b.ToTable(DistributionConsts.DbTablePrefix + \"Manifests\", DistributionConsts.DbSchema);
            b.ConfigureByConvention();
            b.OwnsOne(b => b.TimeWindow);
        });

我们将 TimeWindow 值对象添加到的实体:

public class Manifest : FullAuditedAggregateRoot<Guid>
    {
        protected Manifest()
        {
        }

        public Manifest(
            Guid id) : base(id)
        {
        }

        public virtual TimeWindow TimeWindow { get; set; }
    }

我们有另一个具有不同 ValueObject 的实体以相同的方式配置,但没有任何 DateTimes 并且我们没有收到任何错误。 在构建器之前和构建器内部添加.Ignore(x =&gt; x.TimeWindow); 仍然错误(如错误所建议的那样)。

  • 好吧,错误消息说TimeWindow class\"已经被配置为非拥有\".检查模型/配置中该类的用法 - 确保它没有在任何地方用作实体,并且该类型的所有属性都配置有OwnsOne。或者用[Owned] 属性装饰它。
  • 感谢@IvanStoev 的回复,TimeWindow 是全新的,除了上面显示的之外没有其他参考。这就是为什么我很难理解错误信息
  • 自定义 ConfigureByConvention() 方法(此处未显示)有什么作用?或者,如果您将 OwnsOne 电话移到它之前会发生什么?
  • 这是 ABP 框架的一部分,用于为实体 ConfigureByConvention() 配置所有基本属性。删除 ConfigureByConvention() 不起作用。还在构建器之前和构建器内部添加.Ignore(x =&gt; x.TimeWindow); 仍然错误(如错误所建议的那样)。
  • 我只能为 EF Core 发言。对我来说,显然帖子中未显示的一些代码(您的或 ABP 或任何框架/库)正在将您的 TimeWindow 类注册为实体类型(请参阅 EF Core 文档中的 Including types in the model))b.OwnsOne(b =&gt; b.TimeWindow); 电话。找到并消除/修复那个地方。这就是我能说的。

标签: entity-framework asp.net-core entity-framework-core abp


【解决方案1】:
builder.Ignore<TimeWindow>();
builder.Entity<Manifest>(b =>
            {
                b.ToTable(DistributionConsts.DbTablePrefix + "Manifests", DistributionConsts.DbSchema);
                b.ConfigureByConvention();
                b.OwnsOne(b => b.TimeWindow);
            });

添加builder.Ignore&lt;TimeWindow&gt;(); 行将从模型中删除实体类型,并允许我覆盖它并将其配置为OwnsOne

【讨论】:

    【解决方案2】:

    用 [Owned] 装饰拥有的实体也可以解决问题,例如

    using Microsoft.EntityFrameworkCore;
    
    [Owned]
    public class TimeWindow : ValueObject
    

    不相关但相同的错误:当您拥有的实体的 ID 未设置为长时,也会显示此错误。

     public class OwnedEntity : AuditedEntity<Guid> //error
     public class OwnedEntity : AuditedEntity<long> //correct
    

    【讨论】:

      【解决方案3】:

      对于具有 DateTime 属性的自有实体,我遇到了同样的问题。

      就我而言,问题在于我们有一个 DateTimes 的值转换器,例如

      builder.UseValueConverterForType<DateTime>(
         new ValueConverter<DateTime, DateTime>(v => v, 
         v => DateTime.SpecifyKind(v, DateTimeKind.Local)));
      

      我也使用了Ignore 解决方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-03
        • 1970-01-01
        • 2021-01-27
        • 2020-06-24
        相关资源
        最近更新 更多