5

我有一個具有挑戰性的問題,我想在我的實體框架映射中使用反射來查找引用表的所有外鍵,並且我想要列的名稱那是外鍵。實體框架 - 反映在外鍵和關係/關聯

根據another post on SO,我可以通過反射輕鬆找到表格上的導航屬性。但是這不會給我包含外鍵值的屬性或列的名稱。

我試圖做到這一點的原因是,我有大量的表(近40)引用一個項目表。比方說,用戶在名爲「Andew」的項目表中輸入一個新值,然後管理員注意到它實際上只是已有項目「Andrew」的拼寫錯誤。現在我想查找所有對「Andew」的引用,並將這些引用更改爲「Andrew」。我寧願有效地做到這一點,所以使用反向導航屬性會太慢,因爲您必須在修改它們之前加載值。我想要做的是能夠反映表和列的列表,然後直接向數據庫發出更新命令。這將是這個樣子:

var command = String.Format("UPDATE [{0}] SET [{1}] = {{1}} WHERE [{1}] = {{0}}; ", fk.FromTableName, fk.FromColumnName); 
dataContext.ExecuteStoreCommand(command, new Object[] { oldID, newID }); 

在LINQ to SQL這實際上是很容易的...... 20日線反映的LINQ自動生成的代碼,我是做了,但我們最近切換到EF和我通過EF找不到外鍵列的名稱。

我正在尋找的簡單示例:如果我有一個名爲Employee的對象,名爲Manager的導航屬性和ManagerID的外鍵,那麼我想知道Manager是我的導航屬性和底層存儲是ManagerID屬性。我想嚴格通過反射或元數據來做到這一點,所以我可以從它建立一個動物查詢。

+1

你得到了一個投票,所以我認爲我不是唯一有一點麻煩的人理解你之後的事情。你能做'employee.managerId'還是'employee.manager.id'?你必須知道約定是什麼,你的DBA不能只是簡單地改變數據庫,而不用以其他方式影響你的項目。 – Eonasdan

+0

@Eonasdan - 謝謝。我想知道爲什麼我被低估了。我完全重寫了,希望更清楚地說明。不幸的是現在時間更長了,我試圖保持它的簡短。 – pbarranis

回答

1

一旦你使用的鏈接問題的想法,讓你感興趣的EntityType,注意,從EntityTypeBase,其中有一個屬性KeyMembers這是參加的所有EdmMembers集合EntityType繼承實體的關鍵。

每個EdmMember有一個Name這將是您尋求的字符串"ManagerID"

+1

這是一個很好的想法,但我需要在當前對象上獲取外鍵的名稱,而不是外鍵的鍵。這是myObject.ManagerID和myObject.Manager.ID之間的區別。我們不使用Manager.ManagerID的約定 - 我們使用Manager.ID - 所以每列的命名都不相同。 – pbarranis

1

爲了節省時間,我想拋出這個是而不是正確的答案,但您可以通過SQL中的系統視圖進行操作。我已經嘗試了這一點,它的工作原理,但它讓我感到困擾,我可以很容易地通過LINQ to SQL獲取這些數據,但是我根本無法在EF中找到它。如果沒有其他選擇,我將不得不使用下面的解決方案。 (不過,英孚已經有這樣的數據在內部的某個地方......我只是想訪問它。)

select K.name as RelationshipName, T1.name as FromTable, C1.name as FromColumn, T2.name as ToTable, C2.name as ToColumn 
from sys.foreign_keys as K 
join sys.foreign_key_columns as C on K.object_id = C.constraint_object_id 
join sys.columns as C1 on K.parent_object_id = C1.object_id 
join sys.tables as T1 on K.parent_object_id = T1.object_id 
join sys.columns as C2 on K.referenced_object_id = C2.object_id 
join sys.tables as T2 on K.referenced_object_id = T2.object_id 
where C1.column_id = C.parent_column_id 
and C2.column_id = C.referenced_column_id 
and T2.Name = 'Employee' 
order by T1.Name, C1.Name 

希望發佈此錯誤的答案至少是有用的除我之外的人......(還,只是FYI ,這個解決方案需要更多的代碼來處理多列PK - 我的所有列都是單列的)。