我有一个具有挑战性的问题,我希望在我的Entity Framework映射上使用反射来查找引用表的所有外键,并且我想要作为外键的列的名称。
根据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中,这实际上非常简单...... LINQ自动生成代码的20行反射并且我已经完成了,但我们最近切换到EF并且找不到外键列的名称通过EF。
我正在寻找的一个简化示例:如果我有一个名为Employee的对象,其中包含一个名为Manager的导航属性和一个ManagerID的外键,那么我想知道Manager是我的导航属性,底层存储是ManagerID属性。我想通过反射或元数据严格执行此操作,以便我可以从中构建一个动态查询。
答案 0 :(得分:1)
一旦您使用了关联问题中的提示来访问您感兴趣的EntityType
,请注意EntityType
继承自EntityTypeBase
,其KeyMembers
属性EdmMembers
1}}这是参与实体密钥的所有EdmMember
的集合。
每个Name
都有一个"ManagerID"
,它将是您寻找的字符串{{1}}。
答案 1 :(得分:1)
为了节省时间,我想抛弃这是不正确的答案,但你可以通过SQL中的系统视图来做我想要的。我已经尝试了这个并且它可以工作,但它让我觉得我可以通过LINQ to SQL轻松获得这些数据,但我根本无法在EF中找到它。如果没有其他选择,我将不得不使用以下解决方案。 (但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
希望发布这个错误答案至少对我以外的人有用...(另外,仅供参考,此解决方案需要更多代码才能使用多列PK - 我的所有单列都是如此)。< / p>
答案 2 :(得分:0)
问题的答案在另一篇文章中:Read foreign key metadata programatically with Entity Framework 4
请注意,海报的答案对我不起作用。使用@Ashraf的答案,效果很好。