使用 MS SQL Server 生成的约束名称是否可以预测?

Tra*_*er1 4 foreign-key database-design sql-server constraint entity-framework

当您在 CREATE TABLE 脚本中创建主键和外键约束时,会创建命名约束,例如 FK__RecentlyVi__ScId__2764765D ...这些约束是否可预测?IE:如果你在另一台服务器上运行相同的创建脚本,约束名称是否相同?

我问是因为使用实体框架,当您对辅助表有多个引用时,您会获得诸如... Foreign、Foreign1、Foreign2 等属性...有时在重新生成实体模型时,顺序会有所不同...我想出了以下方法来解决这个问题,但想知道“默认”约束名称是否有效,即使我现在使用的是命名约束。

我的解决方法包括在下面。如果我将来再次需要这个,可以重构基于外键和对象类型名称获取实体的属性。

private Contact GetContactMatchForForeignKey(string foreignKeyName)
{
  var props = typeof(Order).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(EdmRelationshipNavigationPropertyAttribute)));
  foreach (var prop in props) {
    var attrs = prop.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), true);
    foreach (var attr in attrs) { 
      var a = (EdmRelationshipNavigationPropertyAttribute)attr;
      if (a.RelationshipName == foreignKeyName && a.TargetRoleName == "Contact") { 
        return (Contact)prop.GetValue(this, null);
      }
    }
  }
  return null;
}

private void SetContactMatchForForeignKey(string foreignKeyName, Contact value)
{
  var props = typeof(Contact).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(EdmRelationshipNavigationPropertyAttribute)));
  foreach (var prop in props) {
    var attrs = prop.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), true);
    foreach (var attr in attrs) { 
      var a = (EdmRelationshipNavigationPropertyAttribute)attr;
      if (a.RelationshipName == foreignKeyName && a.TargetRoleName == "Contact") { 
        prop.SetValue(this, value, null);
        return;
      }
    }
  }
}

public Contact Purchaser
{
  get { return GetContactMatchForForeignKey("FK_..."); }
  set { SetContactMatchForForeignKey("FK_...",value); }
}

public Contact Seller
{
  get { return GetContactMatchForForeignKey("FK_..."); }
  set { SetContactMatchForForeignKey("FK_...",value); }
}
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 7

不,约束名称是完全不可预测的。如果您希望您的名称保持一致,您可以通过手动应用可预测/可重复的名称来正确命名它们。我不知道您将如何在您拥有的代码中执行此操作,但在 T-SQL 中而不是:

CREATE TABLE dbo.foo(bar INT PRIMARY KEY);

CREATE TABLE dbo.blat(bar INT FOREIGN KEY REFERENCES dbo.foo(bar));
Run Code Online (Sandbox Code Playgroud)

(上面的约束的名称类似于PK__foo__DE90ECFF6CF25EF6FK__blat__bar__1B1EE1BE。)

你会说:

CREATE TABLE dbo.foo(bar INT, CONSTRAINT PK_foo PRIMARY KEY (bar));

CREATE TABLE dbo.blat(bar INT, CONSTRAINT fk_foobar FOREIGN KEY(bar) 
  REFERENCES dbo.foo(bar));
Run Code Online (Sandbox Code Playgroud)