【问题标题】:AspNet EF referencing foreign key to fieldAspNet EF 将外键引用到字段
【发布时间】:2017-01-06 12:23:29
【问题描述】:

我有两个模型:

public class Customer
{
    public int Id { get; set; }
    public int Number { get; set; }
    public int ParentNumber { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string Language { get; set; }
}

public class Batch
{
    public int Id { get; set; }
    public int Number { get; set; }
    public string FileName { get; set; }
    public string ArticleNumber { get; set; }
    public string ArticleDescription { get; set; }
    public int Weight { get; set; }
    public DateTime ProductionDate { get; set; }
    public DateTime DeliveryDate { get; set; }
    public DateTime BestBeforeDate { get; set; }
    public DateTime? ApprovedDateTime { get; set; }
    public int CustomerId { get; set; }
    public virtual Customer Customer { get; set; }
}

一个批次可以有一个客户。但由于我们是从另一个系统导入数据,我们决定不接管他们的id's。 现在外键说尝试通过属性Customer.Id找客户

我正在努力实现从Batch.Customer(Id) 获取Customer.Number 的外键点

我将如何在这方面取得成功? 我尝试通过将 Customer.Number 定义为具有 Key 属性的 Key.. 但这使得主键从 Id 变为 Number,这不是我想要的......

【问题讨论】:

  • EF6 还是 EF Core?
  • 我正在使用 EF Core
  • 并且Batch.CustomerId 属性应该与Customer.Number 相关?
  • 你的外键应该总是引用主键。这就是主键的目的,为特定行提供唯一标识符。如果您希望 Number 成为唯一标识符,它应该是您的主键。
  • 不,一直都是这样。我的评论是故意笼统的。我很确定使用不同的属性也支持较低版本的 EF,但这并不意味着这是一个好主意或你应该这样做。除了主键之外,没有什么好的理由为任何东西创建外键,如果您认为有更好的列可以使用,那么这就是该列作为您的主键的论据。

标签: mysql asp.net-mvc entity-framework .net-core entity-framework-core


【解决方案1】:

在 EF Core 之前,您要问的问题在 EF 中是不可能的。幸运的是,在 EF Core 中,它可以通过使用 Alternate Keys 功能来完成。但请注意,为了能够使用它,您的Cusomer.Number 字段应该是唯一的。

该解决方案需要 Fluent API 配置。

首先将Customer.Number 定义为备用键:

modelBuilder.Entity<Customer>()
    .HasAlternateKey(e => e.Number);

然后建立如下关系:

modelBuilder.Entity<Batch>()
    .HasOne(e => e.Customer)
    .WithMany()
    .HasForeignKey(e => e.CustomerId)
    .HasPrincipalKey(e => e.Number);

最后两行将满足您的需求。

附带说明,最好将属性(和列)命名为CustomerNumber,以避免混淆其中的值。

【讨论】:

  • 抱歉这么晚才回来。我自己已经弄清楚了,我按照建议使用了模型构建器。但没有定义 HasAlternateKey 这是我的模型构建器:builder.Entity&lt;Batch&gt;() .HasOne&lt;Customer&gt;() .WithMany() .HasPrincipalKey(k =&gt; k.Number) .HasForeignKey(k =&gt; k.CustomerId) .OnDelete(DeleteBehavior.Cascade);
  • 是的,看起来当您指定HasPrincipalKey 时,它实际上为您创建了备用键(两者都在Number 列上产生唯一索引)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多