Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composite Key EF Core getting error when using Fluent Api

So I have the following class in Entity Framework Core. I am trying to do a code first migration and can't for the life of me figure out how to make the fluent API for this work.

public class Participants
{
    public Activity Activity { get; set; } //Class with Id and Name of Activity
    public ApplicationUser Participant { get; set; } 

    [Key]
    [Column(Order = 1)]
    public int ActivityId { get; set; }


    [Key]
    [Column(Order = 2)]
    public string ParticipantId { get; set; }
}

In EF6 I was able to do this in OnModelCreating to get it to work fine.

 modelBuilder.Entity<Attendance>()
            .HasRequired(a => a.Activity)
            .WithMany()
            .WillCascadeOnDelete(false);

But in EF Core I get

" Entity type 'Participants' has composite primary key defined with data annotations. To set composite primary key, use fluent API."

I have tried using

modelBuilder.Entity<Participants>().HasKey(p => new {p.Activity, p.Participant});

But, that just leads to

Introducing FOREIGN KEY constraint 'FK_Participants_AspNetUsers_ParticipantId' on table 'Participants' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

If there is a better way to do the whole thing I'm open to suggestions. If you have pluralsight subscription, I'm basically trying to get "Become a Full Stack Developer" by Mosh Hamedani to work in EF core. The example is in "13-full-stack-fundamentals" folder.

UPDATE: Also tried

        modelBuilder.Entity<Participants>()
            .HasOne(p => p.Activity)
            .WithMany()
            .OnDelete(DeleteBehavior.Cascade);

Still got

"Entity type 'Participants' has composite primary key defined with data annotations. To set composite primary key, use fluent API."

UPDATE 2: After trying Roy's suggestion this is what I'm getting

Introducing FOREIGN KEY constraint 'FK_Participants_AspNetUsers_ParticipantId' on table 'Participants' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

UPDATE 3: In the Migration

I removed one of the OneDelete: ReferntialAction.Cascade and it worked. I removed the one off of FK_Participants_AspNetUsers_ParticipantId.

I also changed to this in my OnModelCreating

        modelBuilder.Entity<Participants>()
            .HasKey(p => new { p.ActivityId, p.ParticipantId });
        base.OnModelCreating(modelBuilder);

        //Added this ( Not sure if it's needed if anyone knows let me know) 
        modelBuilder.Entity<Participants>()
            .HasOne(p => p.Activity)
            .WithMany()
            .OnDelete(DeleteBehavior.Cascade);
like image 728
vgwizardx Avatar asked Apr 30 '17 21:04

vgwizardx


People also ask

How do you set composite primary key in fluent API?

The only way to configure composite keys is to use the HasKey method. You specify the properties that form the composite key by passing them in as properties of an anonymous type to the HasKey method.

Does EF core support fluent API?

Entity Framework Fluent API is used to configure domain classes to override conventions. EF Fluent API is based on a Fluent API design pattern (a.k.a Fluent Interface) where the result is formulated by method chaining. In Entity Framework Core, the ModelBuilder class acts as a Fluent API.

How do you configure a primary key for an entity in Entity Framework fluent API?

Configuring a primary key By convention, a property named Id or <type name>Id will be configured as the primary key of an entity. Owned entity types use different rules to define keys. You can configure a single property to be the primary key of an entity as follows: Data Annotations.

What is a composite primary key in EF Core?

A composite primary key is a primary key that contains more than one column. In EF Core, to create a primary key with one column, you would use the [Key] attribute. To create a composite primary key with multiple columns, you have to override DbContext.OnModelCreating () and then specify all of the columns included in the primary key, like this:

What is Entity Framework Core fluent API?

Entity Framework Core Fluent API configures the following aspects of a model: Model Configuration: Configures an EF model to database mappings. Configures the default Schema, DB functions, additional data annotation attributes and entities to be excluded from mapping.

How do I setup a composite key in fluent?

Composite keys can only be configured using the Fluent API; conventions will never setup a composite key, and you can not use Data Annotations to configure one. By convention, on relational databases primary keys are created with the name PK_<type name>.

What is efef fluent API?

EF Fluent API is based on a Fluent API design pattern (a.k.a Fluent Interface) where the result is formulated by method chaining . In Entity Framework Core, the ModelBuilder class acts as a Fluent API. By using it, we can configure many different things, as it provides more configuration options than data annotation attributes.


1 Answers

What you are trying to do is create a relationship between Activity and Participant which is a little different in EFCore.

To do it, you would need to reference the ForeignKey Properties instead of NavigationProperties in the modelbuilder as follows:

    modelBuilder.Entity<Participants>()
        .HasKey(p => new { p.ActivityId , p.ParticipantId });
like image 122
Roy Sanchez Avatar answered Oct 18 '22 00:10

Roy Sanchez