【问题标题】:EF Core non-primitive type value object as primary key?EF Core 非原始类型值对象作为主键?
【发布时间】:2018-12-22 03:10:28
【问题描述】:

我一直在尝试将值对象用作实体框架核心中的唯一 ID。我已经到了正确保存到数据库的地步,但是 EF 没有正确查询数据库以找到我的实体。看起来 EF 正在加载整个表,然后在内存中进行映射。当我查看查询时,它不包含 id 的谓词。

我正在处理一个现有数据库,该数据库使用 10 个字符串 id 和填充零,因此我正在查看将它们作为值对象使用是否可行。我接下来要尝试的只是使用 Guid 并将“SalesOrderNumber”作为单独的字段。不过,这只是针对这种情况,我真正想弄清楚的是是否可以将值对象用作实体框架中的主键。

实体:

public class SalesOrder: Entity<SalesOrderNumber>
    {
        private SalesOrder() { }

        public SalesOrder(SalesOrderNumber id, DateTime dueDate)
        {
            Id = id;
            DueDate = dueDate;
            Open = true;
        }

        public override SalesOrderNumber Id { get; protected set; }
        public DateTime DueDate { get; private set; }
        public bool Open { get; private set; }
    }

值对象:

  public class SalesOrderNumber: ValueObject
    {
        private readonly string _salesOrderNumber;

        public SalesOrderNumber(string salesOrderNumber)
        {
            if (string.IsNullOrWhiteSpace(salesOrderNumber) || salesOrderNumber.Length > 10)
                throw new InvalidOperationException($"Sales Order Number  {salesOrderNumber} is invalid");

            _salesOrderNumber= salesOrderNumber;
        }

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

        public override string ToString() => _salesOrderNumber;
    }

数据库配置:

public void Configure(EntityTypeBuilder<SalesOrder> builder)
        {
            builder.HasKey(e => e.Id);
            builder.Property(e => e.Id).HasConversion(number => number.ToString(), s => new SalesOrderNumber(s));

        }

我查看了其他一些 SO 帖子,但没有一个解决了我遇到的查询问题: EF Core / DbContext > Map custom type as primary key

【问题讨论】:

  • WorkOrderNumber 应该是 SalesOrderNumber,对吧? “工单号……”也是如此。
  • @Hermann.Gruber 是的!我的错。正在与两者合作,以某种方式将它们混合在一起。固定!

标签: entity-framework-core domain-driven-design


【解决方案1】:

您提出的性能问题似乎是 github 上报告的一个未解决问题: EF Core non-primitive type value object as primary key?

有人还报告了一个快速修复: https://github.com/aspnet/EntityFrameworkCore/issues/13669#issuecomment-439589393 如果我理解快速修复的正确方法,将值对象的隐式转换运算符添加到支持原始类型,以及向后方向的隐式转换运算符,可能会解决您的问题。如果这对您有用,请发表评论。

【讨论】:

  • 不错!很棒的发现!我将很快对此进行测试,感谢您指出这一点。我将不得不花更多时间在 EF 核心 github 上。
  • 在终于开始尝试这个之后,这几乎是解决方案,但不适用于 Guid。 7 天前,EF Core 团队发布了一个错误修复,解决了将在 3.0 中发布的问题
  • @ErpaDerp 很好!您介意发布您提到的问题的 github 链接吗?
  • 是否可以转换包含两个字段的非原始值对象? :public class MyId { public int CompanyId; public int UserId }
  • @zolty13 是的,这是可能的。 docs.microsoft.com/en-us/ef/core/modeling/…
猜你喜欢
  • 2021-06-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 2016-03-30
相关资源
最近更新 更多