【问题标题】:Mapping a composite table to a table of default values in EF Core将复合表映射到 EF Core 中的默认值表
【发布时间】:2019-05-11 21:02:32
【问题描述】:

我在数据库中有一个简单的结构:

CREATE TABLE user_categories (
    user_id INT NOT NULL,
    category_id INT NOT NULL,
    PRIMARY KEY (user_id, category_id)
);

CREATE TABLE user_defaults (
    user_id INT NOT NULL,
    category_id INT NOT NULL,
    PRIMARY KEY (user_id),
    FOREIGN KEY (user_id, category_id) REFERENCES user_categories (user_id, category_id)
);

这里的意图是用户分配了一组类别,并且有一个带有默认表的表(可能还有其他列)

但是我很难将其映射到 EF Core,但我总是在 user_categories 表中获得额外的列。

我的UserCategory 班级:

using System.ComponentModel.DataAnnotations.Schema;

namespace EMMA.Authorization.Domain.Entities
{
    public class UserCategory
    {
        public int UserId { get; set; }    
        [ForeignKey(nameof(UserId))]
        public User User { get; set; }

        public int CategoryId { get; set; }
        [ForeignKey(nameof(CategoryId))]
        public Category Category { get; set; }

        public UserDefaults UserDefaults { get; set; }
    }
}

UserDefaults

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace EMMA.Authorization.Domain.Entities
{
    public class UserDefaults
    {
        public int UserId { get; set; }
        public int CategoryId { get; set; }

        public virtual ICollection<UserCategory> UserCategories { get; set; }
    }
}

这是应该配置关系的OnModelCreating方法:

modelBuilder.Entity<UserCategory>().HasKey(s => new { s.UserId, s.CategoryId });
modelBuilder.Entity<UserDefaults>().HasKey(s => s.UserId);
modelBuilder.Entity<UserDefaults>()
    .HasMany(s => s.UserCategories)
    .WithOne(s => s.UserDefaults)
    .HasForeignKey(s => new { s.UserId, s.CategoryId })
    .IsRequired();

但这是我在尝试创建迁移时遇到的异常:

从 'UserCategory.UserDefaults' 到 'UserDefaults.UserCategories' 与外键属性 {'UserId' : int, 'CategoryId' : int} 的关系不能以主键 {'UserId' : int} 为目标,因为它不是兼容的。为此关系配置一个主键或一组兼容的外键属性。

如何在 EF Core 中配置这样的关系,如 SQL 所示?

【问题讨论】:

    标签: c# entity-framework-core


    【解决方案1】:

    user_catagories 对象应该有一个复合键。您已经通过将另一个表中的 FK 作为第一个表上的复合键来暗示这一点。 EF 抱怨,因为这实际上是不正确的。您可以通过将两个成员注释为主要成员来修复它,如下所示:

    public class UserCatagory
    {
          [Key, Column(Order = 0)]
          public int UserId { get; set; }
    
          [Key, Column(Order = 1)]
          public int CategoryId { get; set; }
    
          // Etc...
    }
    

    【讨论】:

    • 您好,它有一个复合键。 modelBuilder.Entity&lt;UserCategory&gt;().HasKey(s =&gt; new { s.UserId, s.CategoryId });
    【解决方案2】:

    我实际上意识到我确实声明了错误的关系,不是一对多,而是一对一。声明以下映射按预期工作:

    modelBuilder.Entity<UserCategory>()
        .HasOne(s => s.UserDefaults)
        .WithOne(s => s.UserCategory)
        .HasForeignKey<UserDefaults>(s => new { s.UserId, s.CategoryId })
        .IsRequired();
    

    【讨论】:

      猜你喜欢
      • 2020-05-03
      • 1970-01-01
      • 2011-12-31
      • 2019-02-04
      • 2020-06-12
      • 2019-08-17
      • 2018-12-21
      • 2020-06-25
      相关资源
      最近更新 更多