簡體   English   中英

一對多 (EF Core) 的建議

[英]Recommendations for a One to Many (EF Core)

我試圖找出定義與客戶和地址有關的一對多關系表的最佳方法。 每個客戶可以有多個地址(郵寄、賬單、交付等)。 地址的類型存儲在一個單獨的表 (AddressType) 中。

這是我所擁有的:

public class Company
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public List<Address> Addresses { get; set; }
    }

  public class Address
    {
        public int Id { get; set; }
        public int AddressTypeId { get; set; }
        public AddressType AddressType { get; set; }
        public string Street1 { get; set; }
        public string Street2 { get; set; }
        public string City { get; set; }
        public int StateId { get; set; }
        public State State { get; set; }
        public string PostalCode { get; set; }
        public int CountryId { get; set; }
        public Country Country { get; set; }
        public bool Active { get; set; }
        public int CompanyId { get; set; }
    }

    public class AddressType
    {
        public int Id { get; set; }
        public string Display { get; set; }
        public bool Active { get; set; }
    }

幾個問題...

  1. 我上面的內容會被認為是好的做法嗎? 如果不是,你會如何定義它?
  2. 假設 AddressType 表包含 Mailing、Billing 和 Delivery,我將如何發出 Linq 查詢,而我只想提取 Mailing Address?

謝謝一堆。

--- 值

我建議使用“基本”地址 class。 Mailing、Billing、Delivery 等將從這個基礎 class 繼承。

public class Address
{
    public string Street { get; set; }

    public int HouseNumber { get; set; }

    public string HouseNumberAddition { get; set; }

    public string City { get; set; }

    public string Country { get; set; }
}

在送貨的情況下,您可能需要為送貨司機打印地址為 label 的送貨單。 但是在基本地址 class 中包含 DeliveryNote 是沒有意義的,因為賬單地址什么時候需要送貨單?

因此,您從基本地址 class 繼承來創建特定的地址類型。

例如:

public class DeliveryAddress : Address
{
    public string DeliveryNote { get; set; } = "Please don't ring the bell after 10pm."
}

假設您使用 EF Code First,實體框架會創建一個Address表,其中包含一個discriminator列。 保存新地址時, discriminator器列定義地址類型。

var googleCompany = new Company
{
    DeliveryAddress = new DeliveryAddress
    {
        Street = "Google Street",
        HouseNumber = 1,
        DeliveryNote = "Watch out for the dog."
    },
    CompanyAddress = new CompanyAddress()
};

var microsoftCompany = new Company
{
    DeliveryAddress = new DeliveryAddress
    {
        Street = "Microsoft Street",
        HouseNumber = 2,
        DeliveryNote = "Don't bring an Apple device on the premise."
    },
    CompanyAddress = new CompanyAddress()
};


_context.Companies.Add(googleCompany);
_context.Companies.Add(microsoftCompany);
_context.SaveChanges();

現在要查詢公司並指定您需要的地址類型,您只需調用include並讓 EF Core 包含地址。

var companiesWithBothDeliveryAddress = 
    _context.Companies.Include(x => x.CompanyAddress)
                      .Include(x => x.DeliveryAddress).ToList();

var companiesWithOnlyDeliveryAddress =
    _context.Companies.Include(x => x.DeliveryAddress).ToList();

EF Fluent API 配置應該是這樣的:

        protected override void OnModelCreating(ModelBuilder builder)
        {
            // Company to CompanyAddress, without inverse property on CompanyAddress.
            builder.Entity<Company>()
                .HasOne(x => x.CompanyAddress)
                .WithOne()
                .HasForeignKey<Company>(x => x.CompanyAddressId)
                .IsRequired(false)
                .OnDelete(DeleteBehavior.NoAction);

            // Company to DeliveryAddress, without inverse property on DeliveryAddress.
            builder.Entity<Company>()
                .HasOne(x => x.DeliveryAddress)
                .WithOne()
                .HasForeignKey<Company>(x => x.DeliveryAddressId)
                .IsRequired(false)
                .OnDelete(DeleteBehavior.NoAction);

            // We let all the Address types share the 'CompanyId' column, 
            // otherwise, EF would create a seperate CompanyId column for all of them.
            builder.Entity<Address>()
                .Property(x => x.CompanyId)
                .HasColumnName(nameof(Address.CompanyId));

            builder.Entity<CompanyAddress>()
                .Property(x => x.CompanyId)
                .HasColumnName(nameof(Address.CompanyId));            
            
            builder.Entity<DeliveryAddress>()
                .Property(x => x.CompanyId)
                .HasColumnName(nameof(Address.CompanyId));

            base.OnModelCreating(builder);
        }

        public DbSet<Address> Addresses { get; set; }

        public DbSet<DeliveryAddress> DeliveryAddresses { get; set; }

        public DbSet<CompanyAddress> CompanyAddresses { get; set; }
        

結果將如下所示:

地址表(為了簡潔,我省略了一些列)

在此處輸入圖像描述

公司表(為簡潔起見,我省略了一些列)

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM