简体   繁体   中英

Creating composite primary key consisting off foreign keys in fluent API with ASP.NET core

The question here is how can i generate a composite primary key consisting of two foreign keys?

I have tried:

public class ActiveQuestions_Questions 
{
    [Column(Order = 0), Key, ForeignKey("ActiveQuestion")]
    public string ActiveQuestionId {get; set;}

    [Column(Order = 1), Key, ForeignKey("Question")]
    public string QuestionId {get; set; }
}

Which gives me: Entity type 'ActiveQuestions_Questions' has composite primary key defined with data annotations. To set composite primary key, use fluent API.

Then i tried using the fluent api in the model builder without the annotations.

builder.Entity<ActiveQuestions_Questions>(
            build => 
            {
                build.HasKey(t => new {t.ActiveQuestionId, t.QuestionId}); 
                build.HasOne(t => t.QuestionId).WithOne().HasForeignKey<Question>(qe => qe.QuestionId);
                build.HasOne(t => t.ActiveQuestionId).WithOne().HasForeignKey<ActiveQuestion>(qe => qe.ActivateQuestionId); 
            }
        );    

Which gave me : The navigation property 'QuestionId' cannot be added to the entity type 'ActiveQuestions_Questions' because a property with the same name already exists on entity type 'ActiveQuestions_Questions'.

Anyone that can point me in the right direction?

The Questions class

public class Question 
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string QuestionId {get; set;}

    [Required]
    public string Text {get; set;}
}

The ActiveQuestion class:

public class ActiveQuestion 
{
    private DateTime _lastUpdated = DateTime.Now; 

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string ActivateQuestionId {get; set;}

    public DateTime LastUpdated 
    {
        get 
        {
            return this._lastUpdated; 
        }
        set 
        {
            this._lastUpdated = value;
        }
    }
}

In EF Core, defining composite PK using KeyAttribute is not supported, therefore you must use fluent API to configure composite PK.

build.HasKey(t => new {t.ActiveQuestionId, t.QuestionId}); 

Above syntax you used in your code is correct way to define composite PK. For more information see Keys in docs.

The reason your code fails is the incorrect configuration of relationship. HasOne / WithOne API are supposed to be used with navigation properties (properties which targets other entity types). In your configuration you are passing a primitive property in HasOne call. Since there is already property with same name added in the model (through conventions & HasKey call), it throws above exception. Even if they hadn't been added, there would be different exception. Here is the link to docs on how to define relationships using fluent API.

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