我在数据库中有一个简单的结构:
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();
但是,当我尝试创建迁移时却遇到了例外情况:
具有外键属性{'UserId':int,'CategoryId':int}的从'UserCategory.UserDefaults'到'UserDefaults.UserCategories'的关系无法针对主键{'UserId':int},因为它不是兼容。为此关系配置一个主键或一组兼容的外键属性。
如何在EF Core中配置SQL中所示的这种关系?
答案 0 :(得分:0)
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...
}
答案 1 :(得分:0)
我实际上意识到我确实声明了错误的关系,它不是一对多的,而是一对一的。声明以下映射将按预期工作:
modelBuilder.Entity<UserCategory>()
.HasOne(s => s.UserDefaults)
.WithOne(s => s.UserCategory)
.HasForeignKey<UserDefaults>(s => new { s.UserId, s.CategoryId })
.IsRequired();