【问题标题】:Entity Framework Core: Restricting foreign key columns from being equal to each otherEntity Framework Core:限制外键列彼此相等
【发布时间】:2019-02-01 16:31:04
【问题描述】:

我正在使用 Entity Framework Core 2.2 来管理交易货币的 SQL Server 数据库。模型中有两个实体。第一个是Currency,它指定了一种可交易的货币,另一个是CurrencyPair,它指定了一对可以相互兑换的货币。

public class Currency
{
    public ulong Id { get; set; }
    public string Name {get; set; }

    [NotMapped]
    public IEnumerable<CurrencyPair> Pairs
    {
        get { PairsAsBase?.Concat( PairsAsQuote ?? new CurrencyPair[0] ); }
    }

    public virtual IEnumerable<CurrencyPair> PairsAsBase { get; set; }
    public virtual IEnumerable<CurrencyPair> PairsAsQuote { get; set; }
}

public class CurrencyPair
{
    public ulong Id { get; set; }
    public string Name { get; set; }
    public ulong BaseCurrencyId { get; set; }
    public ulong QuoteCurrencyId { get; set; }

    public virtual Currency BaseCurrency { get; set; }
    public virtual Currency QuoteCurrency { get; set; }
}

我想限制 CurrencyPair 表以禁止行在 BaseCurrencyQuoteCurrency 字段中具有相同的 Currency。也就是说,如果特定货币有Id = 1,则不允许指定BaseCurrencyId = 1QuoteCurrencyId = 1 的货币对。

这是我的DbContext.OnModelCreating 实现:

protected override void OnModelCreating( ModelBuilder modelBuilder )
{
    modelBuilder.Entity<Currency>().HasKey(x => x.Id);
    modelBuilder.Entity<Currency>().HasAlternateKey(x => x.Name);
    modelBuilder.Entity<Currency>()
                .HasMany(x => x.PairsAsBase)
                .WithOne(x => x.BaseCurrency)
                .HasForeignKey(x => x.BaseCurrencyId);
    modelBuilder.Entity<Currency>()
                .HasMany(x => x.PairsAsQuote)
                .WithOne(x => x.QuoteCurrency)
                .HasForeignKey(x => x.QuoteCurrencyId);

    modelBuilder.Entity<CurrencyPair>().HasKey(x => x.Id);
    modelBuilder.Entity<CurrencyPair>()
                .HasOne(x => x.BaseCurrency)
                .WithMany(x => x.PairsAsBase)
                .HasForeignKey(x => x.BaseCurrencyId);
    modelBuilder.Entity<CurrencyPair>()
                .HasOne(x => x.QuoteCurrency)
                .WithMany(x => x.PairsAsQuote)
                .HasForeignKey(x => x.QuoteCurrencyId);
}

TL;DR:如何确保表中的两个外键列不会同时引用同一个实体(使用 Entity Framework Core 2.2)?

【问题讨论】:

  • 我会说没有真正好的方法可以做到这一点。您可以使用触发器之类的东西来限制它,但我个人不会这样做。您是否考虑过在数据进入数据库之前验证这些数据?
  • 验证客户端并检查数据库中的约束。哪个 RDBMS?
  • 这对于数据库上的简单CHECK 约束来说是微不足道的。类似的事情会做:ALTER TABLE CurrencyPair ADD CONSTRAINT CK_CurrencyPair_DifferentCurrencies CHECK (BaseCurrency &lt;&gt; QuoteCurrency) ;

标签: c# entity-framework entity-framework-core


【解决方案1】:

AFAIK 没有好的方法可以在模型构建器 lvl 中强制执行您的规则。 下一个最好的方法是拦截可能通过 ef 上下文生成错误数据的 SQL 命令,但 API 还不够成熟,无法轻松选择。

在我看来,您剩下的唯一选项与 EF 没有任何关系:

  • 约束:在您的数据库架构上强制执行规则,例如。通过CHECK 约束
  • 验证:在域模型级别强制执行规则,例如。通过拦截类中两个属性的设置器并验证它们的值。

【讨论】:

    【解决方案2】:

    您是否尝试过全局查询过滤器,这应该可以帮助您在查询时保护一些不需要的内容

    modelBuilder.Entity<CurrencyPair>().HasQueryFilter(p => p.BaseCurrency != p.QuoteCurrency);
    

    数据仍会存储在您的表格中,但在您使用时不会显示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-22
      • 1970-01-01
      • 2018-09-28
      • 2016-12-16
      • 1970-01-01
      • 2018-08-19
      • 1970-01-01
      • 2021-09-18
      相关资源
      最近更新 更多