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);
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.
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.
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.
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:
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.
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>.
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.
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 });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With