代码之家  ›  专栏  ›  技术社区  ›  JED

一对多,一个主在代码优先实体框架核心

  •  0
  • JED  · 技术社区  · 6 年前

    一个公司可以有许多地址,但是每个公司都有一个主地址。

    我在寻找在ef core中建立这种关系的最佳方法。

    下面是我想到的。有更好的办法吗?我完全离开了吗?


    模型

    public class Company
    {
        public int Id { get; set; }
    
        public int MainAddressId { get; set; }
        public Address MainAddress { get; set; }
    
        public ICollection<CompanyAddress> CompanyAddresses { get; set; }
    
        // other company info
    }
    
    public class Address
    {
        public int Id { get; set; }
    
        public int CompanyAddressId { get; set; }
        public CompanyAddress CompanyAddress { get; set; }
    
        // other address info
    }
    
    public class CompanyAddress
    {
        public int CompanyId { get; set; }
        public Company Company { get; set; }
    
        public int AddressId { get; set; }
        public Address Address { get; set; }
    
        public bool IsMain { get; set; }
    }
    


    数据上下文.cs

    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions<DataContext> options) : base(options)
        {
        }
    
        public DbSet<Company> Companies { get; set; }
        public DbSet<Address> Addresses { get; set; }
        public DbSet<CompanyAddress> CompanyAddresses { get; set; }
    
        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<CompanyAddress>()
                .HasKey(ca => new {ca.CompanyId, ca.AddressId});
    
            builder.Entity<CompanyAddress>()
                .HasOne(ca => ca.Company)
                .WithMany(ca => ca.CompanyAddresses)
                .HasForeignKey(ca => ca.CompanyId)
                .OnDelete(DeleteBehavior.Cascade);
    
            builder.Entity<CompanyAddress>()
                .HasOne(ca => ca.Address)
                .WithOne(ca => ca.CompanyAddresses)
                .HasForeignKey(ca => ca.AddressId)
                .OnDelete(DeleteBehavior.Cascade);
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   John White    6 年前

    在我看来,死定了。总有别的办法。但这是直截了当的,很容易理解。mainaddress和mainaddressid是多余的。您没有延迟加载(虚拟),因此可以通过

    dbContext.Companies.FirstOrDefault(p => p.Id = <myCompanyId>);
    dbContext.CompanyAddresses.FirstOrDefault(p => p.CompanyId == <myCompanyId> && p.IsMain);
    

    如果以后再进行延迟加载,只需将.include(“address”)添加到第二个查询。是的,你可以把两者结合起来。