【问题标题】:EF core 3.1 - common table for entity and owned typeEF core 3.1 - 实体和拥有类型的公用表
【发布时间】:2021-01-27 04:12:45
【问题描述】:

我正在尝试在我的项目中实施 DDD 方法,但我意识到我的聚合太大,并试图最大限度地减少从数据库加载的数据量。我有一个聚合Order,在某些操作期间它依赖于另一个聚合-Company。要执行操作 RefreshOrderNumber() 我需要来自 Company 实体的三个属性,并且对 **Company 的其他字段完全不感兴趣。所以,我想到了为 Order - OrderCompanyInfo 创建一个值类型并将这些字段封装在上面

public class Company
{
   public Id {get;private set;}
   public string Name {get; private set;}
   public string Currency {get; private set;}
   public string DocumentPrefix {get; private set;}
   // other ~15 fields
}

public class OrderCompanyInfo : ValuableType
{
   private OrderCompanyInfo ()
   {

   }
  
   public long CompanyId {get; private set;}
   public string Name {get; private set;}
   public string Currency {get; private set;}
   public string DocumentPrefix {get; private set;}
  
  public static OrderCompanyInfo Create(Company company)
  {
     return OrderCompanyInfo {
       CompanyId = company.Id,
       Name = company.Name,
       Currency = company.Currency ,
       DocumentPrefix = company.DocumentPrefix 
     }

  }
}

public class Order
{

  private Order()
  {
     
  }

  public Order(OrderCompanyInfo companyInfo)
  {
    CompanyInfo = companyInfo; 
    AddLog();
  }

  public OrderNumberInfo OrderNumber {get; private set;}
  public OrderCompanyInfo CompanyInfo {get; private set;}

 

  public void DoSomethingImportant()
  {
    RefreshOrderNumber();
    AddLog();
  }

  private void AddLog()
  {
     //Add log entry using CompanyInfo.Name
  }

  private void RefreshOrderNumber()
  {
     //Create new OrderNumberInfo using OrderCompanyInfo.Currency and OrderCompanyInfo.DocumentPrefix 
  }
}

现在我正在尝试使其与 EF 核心一起使用。基本上 OrderCompanyInfo 应该使用 OwnOne() 方法配置并映射到与 Company 实体相同的表,因此数据在订单期间始终是实际的通过存储库聚合加载。所以我有这个订单聚合的配置:

public override void Configure(EntityTypeBuilder<Order> builder)
{
    builder.OwnsOne(x => x.InventoryOwnsCompanyProfile, opt =>
             {
                 opt.ToTable("Company"); 

                 opt.HasOne<Company>()
                    .WithOne()
                    .HasForeignKey<OrderCompanyInfo>(x => x.CompanyId);
             });
}

但是尝试这种方式会给我一个错误:

Cannot use table 'dbo.Company' for entity type 'OrderCompanyInfo ' since it is being used for entity type 'Company' and there is no relationship between their primary keys.

有没有办法让 EF 核心以这种方式工作?

【问题讨论】:

    标签: c# asp.net entity-framework domain-driven-design


    【解决方案1】:

    好的,答案是在 GitHub 社区上找到的。 https://github.com/dotnet/efcore/issues/13162#issuecomment-417411405

    他们提供了一个示例,其中两个实体映射到同一个表

    namespace One
    {
        public class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
    }
    
    namespace Two
    {
        public class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public DateTime Birthday { get; set; }
        }
    }
    
    public class BloggingContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            => optionsBuilder
                .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test;ConnectRetryCount=0");
    
        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<One.Person>(b =>
            {
                b.HasOne<Two.Person>().WithOne().HasForeignKey<Two.Person>(e => e.Id);
                b.ToTable("People");
                b.Property(e => e.Name).HasColumnName(nameof(One.Person.Name));
            });
    
            builder.Entity<Two.Person>(b =>
            {
                b.ToTable("People");
                b.Property(e => e.Name).HasColumnName(nameof(Two.Person.Name));
            });
        }
    }
    
    

    我试图将 OrderCompanyInfo 构建为 Owned 类型是错误的,因为拥有类型意味着拥有类型与所有者之间的关系。在我的场景中,这将导致 Company 表将具有 OrderId 字段的情况,这至少是不正确的。通过 HasOne() 配置 OrderCompanyInfo 实体非常适合我

    【讨论】:

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