我确定这很简单,但找不到答案可能是因为我不知道如何表达我的问题。
我正在尝试将两个不同的“竞争对手”分配给一个“游戏”作为“玩家”和“对手”。
我的模特
public class Competitor{
public int CompetitorId { get; set; }
// other properties
}
public class Game{
public int GameId { get; set; }
public int PlayerId { get; set; }
public int OpponentId { get; set; }
public Competitor Player { get; set; } // This should use PlayerId to return a Competitor
public Competitor Opponent { get; set; } // This should use OpponentId to return a Competitor
}
我试过使用 ForeignKey 的注释,甚至尝试使用 FluentAPI,但在更新数据库期间不断出现相同的错误:
"Introducing FOREIGN KEY constraint 'FK_Matches_Competitors_PlayerId' on table 'Matches' may cause cycles or multiple cascade paths. 指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引”
你们中的一个漂亮聪明的人可以给我一些感觉吗?谢谢!!!
您可以通过为任一实体注册一个实体配置来解决这个问题,您可以在其中声明该实体的哪个属性以何种方式与另一个实体的属性相关。
在这种情况下,因为我猜游戏更依赖于竞争者而不是相反,我们将做一个
GameConfiguration
:
using Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Infrastructure.Data.PostgreSql.Configurations
{
public class GameConfiguration : IEntityTypeConfiguration<Game>
{
public void Configure(EntityTypeBuilder<Game> game)
{
game.HasOne(game => game.Player)
.WithMany()
.HasForeignKey(game => game.PlayerId)
.OnDelete(DeleteBehavior.Restrict); // restricts deletion of a Player Competitor participating in this relationship.
game.HasOne(game => game.Opponent)
.WithMany()
.HasForeignKey(game => game.OpponentId)
.OnDelete(DeleteBehavior.Cascade); // restricts deletion of a Opponent Competitor participating in this relationship.
}
}
}
然后在您的
Context
课程中,您在 OnModelCreating
期间应用配置。您可以显式地为该配置执行此操作,或者告诉上下文在给定程序集中查找所有配置类。
using Domain.Entities;
using Infrastructure.Data.PostgreSql.Configurations;
using Microsoft.EntityFrameworkCore;
namespace Infrastructure.Data.PostgreSql
{
public class DataContext : DbContext
{
// Properties
public DbSet<Competitor> Competitors => Set<Competitor>();
public DbSet<Game> Games => Set<Game>();
// Constructors
public DataContext(DbContextOptions<DataContext> options) : base(options) { }
// Methods
protected override void OnModelCreating(ModelBuilder model)
{
// Either
model.ApplyConfiguration(new GameConfiguration());
// Or
model.ApplyConfigurationsFromAssembly(typeof(DataContext).Assembly);
}
}
}