EF核心非原始类型值对象作为主键?

时间:2018-11-15 21:32:29

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

我一直在尝试使用值对象作为实体框架核心中的唯一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

1 个答案:

答案 0 :(得分:1)

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

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