Sql-Server
使用 MS SQL Server 生成的約束名稱是否可預測?
當您在 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__DE90ECFF6CF25EF6
。FK__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));