Sql-Server

使用 MS SQL Server 生成的約束名稱是否可預測?

  • January 15, 2018

當您在 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); }
}

不,約束名稱是完全不可預測的。如果您希望您的名稱保持一致,您可以通過手動應用可預測/可重複的名稱來正確命名它們。我不知道您將如何在您擁有的程式碼中執行此操作,但在 T-SQL 中而不是:

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

CREATE TABLE dbo.blat(bar INT FOREIGN KEY REFERENCES dbo.foo(bar));

(上面的約束以 和 之類的名稱結束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));

引用自:https://dba.stackexchange.com/questions/24758