简体   繁体   中英

One-to-many relationship with composite primary key using EF Core

I'm trying to make a one-to-many relationship with a composite primary key:

public class Bom
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]

    public string Id { get; set; }
    public string Name { get; set; }
}

public class ChildReference
{
    [Key]
    public int Id { get; set; }
    public string BomId { get; set; } // Should be the foreign key from the bom-table
    public ICollection<Bom> Boms { get; set; }
}

......

builder.Entity<ChildReference>().HasKey(t => new { t.Id, t.BomId });

When I run this, Entity Framework Core creates two columns in the Bom-table called ChildReferenceBomId and ChildReferenceId . I don't want that. I want it to only create one column caled ChildReferenceId that should be the foreign key to the ChildReference table.

The reason why I want to create a composite primary key inside the ChildReference table is because I want to add rows to the table like this:

  INSERT INTO ChildReference(Id, BomId) VALUES(1, '1')
  INSERT INTO ChildReference(Id, BomId) VALUES(1, '2')

I'm not sure if I'm doing this the right way. Can anyone help me?

EDIT:

I basically want to do the following with entity framework core:

CREATE TABLE [dbo].BOMChildren (
    [BOMChildId] [int] NOT NULL,    
    [BOMId] [int] NOT NULL,
CONSTRAINT [PK_BOMChildId_BOMId] PRIMARY KEY CLUSTERED
(
    [BOMChildId] ASC,
    [BOMId] ASC
))

CREATE TABLE [dbo].BOM (
    [BOMId] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,   
    [BOMPartId] [nvarchar](64) NOT NULL,
    [Qty] [int] NOT NULL,
    [UnitOfMeasure] [nvarchar](32),
    [ParentId] [int] NULL,
    [ChildReference] [int] NULL,
    [BOMItemDataId] [int]
)

ALTER TABLE [dbo].[BOMChildren]  
ADD  CONSTRAINT [FK_BOMChildren_BOM] 
FOREIGN KEY([BOMId]) REFERENCES [dbo].[BOM] ([BOMId])
GO

ALTER TABLE dbo.Bom
  ADD CONSTRAINT FK_Bom_BomChild
  FOREIGN KEY(ChildReference, BOMId) REFERENCES [dbo].BOMChildren([BOMChildId], [BOMId])

Anyone who can push me in the right direction?

You can use set it up like this:

public class Bom
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string Id { get; set; }
    public string Name { get; set; }    
    
    public int ChildReferenceId { get; set; }
    public ChildReference CurrentChildReference{ get; set; }
}

public class ChildReference
{
    [Key]
    public int Id { get; set; }
    public ICollection<Bom> Boms { get; set; }
}

You can after that configure a one-to-many relationship for the above entities using Fluent API by overriding the OnModelCreating method in the context class, as shown here:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // configures one-to-many relationship
    modelBuilder.Entity<Bom>()
            .HasRequired<ChildReference>(s => s.CurrentChildReference)
            .WithMany(g => g.Boms)
            .HasForeignKey<int>(s => s.ChildReferenceId);          
}

You can use the Create/Alter SQL statements that you posted above to create the tables within your database.
After that you can do a Reverse Engineer Model to generate EF code first DbContext based on your existing Database tables.
You can follow the steps within chapter 3 ( https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/workflows/existing-database )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM