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

C# 一对多,一个主代码优先实体框架核心,c#,entity-framework-core,C#,Entity Framework Core,一个公司可以有多个地址,但每个公司都有一个主地址 我正在寻找在EF Core中建立这种关系的最佳方式 下面是我想到的。有更好的办法吗?我完全偏离了吗 型号 public class Company { public int Id { get; set; } public int MainAddressId { get; set; } public Address MainAddress { get; set; } public ICollection<

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

我正在寻找在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; }
}
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);
    }
}
上市公司
{
公共int Id{get;set;}
public int MainAddressId{get;set;}
公共地址主地址{get;set;}
公共ICollection公司地址{get;set;}
//其他公司信息
}
公共课堂演讲
{
公共int Id{get;set;}
public int CompanyAddressId{get;set;}
公共公司地址公司地址{get;set;}
//其他地址信息
}
公共类公司地址
{
public int CompanyId{get;set;}
上市公司{get;set;}
public int AddressId{get;set;}
公共广播地址{get;set;}
公共布尔值为{get;set;}
}

DataContext.cs

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; }
}
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);
    }
}
公共类DataContext:DbContext
{
公共数据上下文(DbContextOptions):基本(选项)
{
}
公共数据库集公司{get;set;}
公共数据库集地址{get;set;}
公共数据库集公司地址{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder)
{
builder.Entity()
.HasKey(ca=>new{ca.CompanyId,ca.AddressId});
builder.Entity()
.HasOne(ca=>ca.Company)
.WithMany(ca=>ca.CompanyAddresss)
.HasForeignKey(ca=>ca.CompanyId)
.OnDelete(DeleteBehavior.Cascade);
builder.Entity()
.HasOne(ca=>ca.Address)
.WithOne(ca=>ca.COMPANY地址)
.HasForeignKey(ca=>ca.AddressId)
.OnDelete(DeleteBehavior.Cascade);
}
}

在我看来,完全正确。总有其他的方法。但这是直截了当的,很容易理解。MainAddress和MainAddressId是冗余的。您没有延迟加载(虚拟),因此可以通过以下方式轻松确定主地址:

dbContext.Companies.FirstOrDefault(p => p.Id = <myCompanyId>);
dbContext.CompanyAddresses.FirstOrDefault(p => p.CompanyId == <myCompanyId> && p.IsMain);
dbContext.companys.FirstOrDefault(p=>p.Id=);
dbContext.companyAddresss.FirstOrDefault(p=>p.CompanyId==&p.IsMain);
如果以后使用延迟加载,只需将.Include(“地址”)添加到第二个查询中即可。是的,你可以把两者结合起来