【问题标题】:Many to Many relationship, bridge table - How to insert duplicate primary key?多对多关系,桥接表 - 如何插入重复的主键?
【发布时间】:2021-02-27 22:32:07
【问题描述】:

我在食谱和星级评分之间存在多对多关系。

一个食谱可能有很多星级评分(来自多个用户)。 星级 (1-5) 可用于许多食谱。

因此,我有一个名为 RecipeStarRatings 的桥接表,其中包含一个 RecipeId 列和一个 StarRatingId 列。

但是,当我尝试为已经具有诸如 RecipeId:1 和 StarRatingId:5 之类的 StarRating 的食谱添加 StarRating 时,我收到了违规消息:

桌子的设计者:

CREATE TABLE [dbo].[RecipeStarRating] (
    [RecipeId]     INT NOT NULL,
    [StarRatingId] INT NOT NULL,
    CONSTRAINT [PK_RecipeStarRating] PRIMARY KEY CLUSTERED ([RecipeId] ASC, [StarRatingId] ASC),
    CONSTRAINT [FK_RecipeStarRating_Recipe_RecipeId] FOREIGN KEY ([RecipeId]) REFERENCES [dbo].[Recipe] ([Id]) ON DELETE CASCADE,
    CONSTRAINT [FK_RecipeStarRating_StarRating_StarRatingId] FOREIGN KEY ([StarRatingId]) REFERENCES [dbo].[StarRating] ([Id]) ON DELETE CASCADE
);


GO
CREATE NONCLUSTERED INDEX [IX_RecipeStarRating_StarRatingId]
    ON [dbo].[RecipeStarRating]([StarRatingId] ASC);

RecipeContext.cs 类的相关部分

            // Declare RecipeId and StarRatingId as primary keys for RecipeStarRating
            modelBuilder.Entity<RecipeStarRating>()              
                .HasKey(t => new { t.RecipeId, t.StarRatingId});

            // Declare many to many for RecipeStarRating
            modelBuilder.Entity<RecipeStarRating>()
                .HasOne<Recipe>(rsr => rsr.Recipe)
                .WithMany(r => r.RecipeStarRatings)
                .HasForeignKey(rsr => rsr.RecipeId);


            // Declare many to many for RecipeStarRating
            modelBuilder.Entity<RecipeStarRating>()
                .HasOne<StarRating>(rsr => rsr.StarRating)
                .WithMany(sr => sr.RecipeStarRating)
                .HasForeignKey(rsr => rsr.StarRatingId);

RecipeStarRating 类

    public class RecipeStarRating
    {
        public int RecipeId { get; set; } 
        public int StarRatingId { get; set; }
        public Recipe Recipe { get; set; }
        public StarRating StarRating { get; set; }
    }

星级等级

    public class StarRating
    {
        public int Id { get; set; }

        [Required] 
        public float Rating { get; set; }

        public ICollection<RecipeStarRating> RecipeStarRating { get; set; }
    }

食谱课

    public class Recipe
    {
        public int Id { get; set; }

        [Required]
        [MaxLength(50)]
        [Column(TypeName= "varchar(50)")]
        public string Name { get; set; }

        [Required]
        [MaxLength(500)]
        [Column(TypeName = "varchar(500)")]
        public string Ingredients { get; set; }

        [Required]
        [MaxLength(2000)]
        [Column(TypeName = "varchar(2000)")]
        public string Instructions { get; set; }

        [Required]
        [MaxLength(500)]
        [Column(TypeName = "varchar(500)")]
        public string ImageURL { get; set; }

        public ICollection<TagRecipe> TagRecipes { get; set; }

        public ICollection<RecipeStarRating> RecipeStarRatings { get; set; }

谢谢

【问题讨论】:

  • 我不明白这里有什么问题。; PK 工作正常。您没有提出任何问题,您只是告诉我们您遇到了一个错误,而该错误字面上告诉您它失败的原因。这里一切正常。
  • “然而”这个词是我试图表明我不想发生的事情正在发生。即,我不希望触发违规行为,我该如何防止这种情况发生?我是不是做错了什么,等等。
  • “我不希望违规触发,如何防止?” 然后删除列上的主键。尽管有 2 行相同可能是设计缺陷。
  • 不要将“评级”值 (1-5) 与 StarRatingId 混淆。将 StarRatingId 视为无意义的键。您想要记录 2 个 5 星评级,这意味着创建一个评级值为 5 的新 StarRating 以关联到配方,而不是将相同的 5 星评级关联两次。 new 使用评级值创建一个新的 StarRating 并将其添加到配方的 StarRatings 中。

标签: c# sql-server entity-framework


【解决方案1】:

您必须创建并添加一个 StarRating。当您向 StarRating 添加更多属性时,这一点变得很明显,因为每个 StarRating 是由不同的用户在不同的时间留下的,例如:

public class StarRating
{
    public int Id { get; set; }

    public DateTime RatingDate {get;set;}

    public string UserName {get;set;}

    [Required] 
    public float Rating { get; set; }

    public ICollection<RecipeStarRating> RecipeStarRating { get; set; }
}

【讨论】:

    猜你喜欢
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 2018-09-04
    • 2014-06-12
    • 2011-12-23
    • 1970-01-01
    相关资源
    最近更新 更多