Asp.net 外键引用标识字段可以吗?

Asp.net 外键引用标识字段可以吗?,asp.net,sql-server,Asp.net,Sql Server,假设在ASP.NET MVC代码优先方法中有以下模型: public class City { public int Id { get; set; } public string Name { get; set; } } public class Restaurant { public int Id { get; set; } public int CityId { get; set; } public virtual City City { get;

假设在ASP.NET MVC代码优先方法中有以下模型:

public class City
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Restaurant
{
    public int Id { get; set; }
    public int CityId { get; set; }
    public virtual City City { get; set; }
} 
这意味着我有一个名为
City
的表,它有:

  • Id(主键,它是一个标识字段)
  • 名称(varchar)
和另一个名为
餐厅
的表,其中包含:

  • Id(主键,它是一个标识字段)
  • CityId(在
    City
    表中引用外键Id,删除时无级联)
现在,由于我的城市数据是固定的,变化不大,我使用种子方法填充它,如下所示:

context.Cities.AddOrUpdate(x => x.Name,
               new City() { Name = "Springfield" },
               new City() { Name = "Franklin" },
               new City() { Name = "Greenville" }
            );
请注意,我没有分配任何ID,因为城市ID是一个标识字段,并且自动递增

一种情况: 我担心的情况是: 假设
餐厅
表中有一些餐厅引用了这些城市。现在随着时间的推移,由于一些未知的原因,Id为2的富兰克林被从
City
表中删除。因此,当您注意到发生了什么时,您会再次插入
Franklin
作为一个城市,但这次它的Id发生了变化。那么,那些已经将“富兰克林”作为自己城市的餐馆会发生什么呢

我应该让城市Id不是一个标识主键,而是一个整数主键,然后自己分配城市Id吗

如果我在外键上启用级联删除,那么我将丢失引用已删除城市的记录,我不希望这样。我想保留它们,直到我弄清楚被删除的城市发生了什么并解决了问题

问题:
在我的例子中,有了这些信息,从身份字段生成外键是一种好的做法吗?处理这种情况的最佳方法是什么?

只要有餐厅引用,就无法从表中删除任何城市

这将由外键强制执行。(您可以在创建外键时对此进行自定义:在删除级联时,在删除时设置NULL…)


所以答案是肯定的:这是一个很好的做法。

只要有餐厅引用,就不能从表中删除任何城市

这将由外键强制执行。(您可以在创建外键时对此进行自定义:在删除级联时,在删除时设置NULL…)


所以答案是肯定的:这是一个很好的实践。

主键和外键确保了所谓的“引用完整性”。就像听起来一样,它们确保了数据中包含的引用的完整性。如果您在某个城市拥有餐厅,则不应允许您删除该城市,因为这会破坏参考资料的完整性(即,您现在拥有孤儿餐厅)。另一种方法是,如果删除城市,则允许数据库删除餐馆。这两种情况(阻止删除或级联删除)都可以使用外键完成

当一个表中的数据依赖于另一个表中的数据时,您应该创建一个外键,以确保不会导致数据损坏。它是标识列这一事实与此无关


您的数据库是防止损坏数据的最后一道防线。您希望确保不允许那些导致删除行的“未知原因”。与在数据损坏后修复数据相比,从一开始就预防问题更容易。

主键和外键确保了所谓的“引用完整性”。就像听起来的那样,它们确保了数据中包含的引用的完整性。如果您在某个城市拥有餐厅,则不应允许您删除该城市,因为这会破坏参考资料的完整性(即,您现在拥有孤儿餐厅)。另一种方法是,如果删除城市,则允许数据库删除餐馆。这两种情况(阻止删除或级联删除)都可以使用外键完成

当一个表中的数据依赖于另一个表中的数据时,您应该创建一个外键,以确保不会导致数据损坏。它是标识列这一事实与此无关


您的数据库是防止损坏数据的最后一道防线。您希望确保不允许那些导致删除行的“未知原因”。首先预防问题比在数据损坏后修复数据更容易。

列是否为identity类型无关紧要。主键和外键用于引用相关表。如果删除主表(如City)中的引用值,则会出现错误。首先必须删除引用该外键值的所有记录。如果以后再次添加城市,则它将具有新id,因为您使用的是标识列。列是否为标识类型与此无关。主键和外键用于引用相关表。如果删除主表(如City)中的引用值,则会出现错误。首先必须删除引用该外键值的所有记录。如果以后再次添加城市,那么它将有一个新id,因为您使用的是标识列。区分“外键”(关系数据库设计中的一个概念)和“外键约束”很重要这是一种可以在SQL Server中的表的列上实现的约束类型,该表强制执行外键列中的数据与相关表中的行之间的关系。数据库模型中外键列的存在不会强制执行引用完整性—这只能通过在表上实现适当的约束来实现。区分“外键”(关系数据库设计中的一个概念)和“外键约束”(关系数据库设计中的一个概念)很重要