实体框架 - 反思外键和关系/关联

时间:2011-11-13 15:18:43

标签: .net entity-framework reflection foreign-keys foreign-key-relationship

我有一个具有挑战性的问题,我希望在我的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属性。我想通过反射或元数据严格执行此操作,以便我可以从中构建一个动态查询。

3 个答案:

答案 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的答案,效果很好。