简体   繁体   English

如何找到与导航属性相关的Id属性?

[英]How can I find the Id property or properties related to a navigational property?

For a project I'm working with Entity Framework and I'd like to be able to enumerate all navigational properties for a given object instance (assuming it's an object generated by EF). 对于我正在使用Entity Framework的项目,我希望能够枚举给定对象实例的所有导航属性(假设它是由EF生成的对象)。 From there I'd like to get the related Id property for every navigational property. 从那里我想获得每个导航属性的相关Id属性。

For example, if I get an instance of the class Person , I want to be able to find it's navigational properties called Address and Boss . 例如,如果我得到Person类的实例,我希望能够找到它的名为Address and Boss的导航属性。 For those two navigational properties I want to then "lookup" the related Id properties called AddressId and BossId . 对于那两个导航属性,我想“查找”名为AddressIdBossId的相关Id属性。

I need those Id properties so I can run queries on a different database which does not have the same foreign keys but does have exactly the same Ids. 我需要那些Id属性,所以我可以在不具有相同外键但具有完全相同的ID的不同数据库上运行查询。

So far I have figured out a way to get the RelationshipManager for a random object instance generated by EF. 到目前为止,我已经想出了一种方法来获取由EF生成的随机对象实例的RelationshipManager And while debugging I can get to the foreign key relations via the Manager's Relationships property. 在调试时,我可以通过Manager的Relationships属性获取外键关系。 But I can only get as far as the navigational property name. 但我只能获得导航属性名称。 So I can see there's a FK_Person_Address which is related to the navigational property called Address but I can't find the AddressId . 所以我可以看到有一个FK_Person_Address与名为Address的导航属性相关,但我找不到AddressId

So my question is, how can I dynamically (with no knowledge of the Person class' layout) discover the AddressId property which is related to Address ? 所以我的问题是,我怎样才能动态地(不知道Person类的布局)发现与Address相关的AddressId属性?

I am aware the Foreign Key relationship might have the Id property on the other side of the relation ( Boss pointing to Person in stead of Person having a BossId ). 我知道外键关系可能在关系的另一端有Id属性( Boss指向Person而不是PersonBossId )。 In that case, I'd still like to discover that Boss has a PersonId when I'm inspecting an instance of Person . 在那种情况下,当我正在检查一个Person实例时,我仍然想发现Boss有一个PersonId

This will give you a dictionary with all navigation properties as Key and all related properties as Value (the value might be a property from the other entity) 这将为您提供一个字典,其中所有导航属性为Key,所有相关属性为Value(该值可能是其他实体的属性)

Add these to your DBContext class and call db.GetForeignKeyProperties<Person>() 将这些添加到您的DBContext类并调用db.GetForeignKeyProperties<Person>()

The result will be something like: 结果将是这样的:

"Address" - "AddressID" “地址” - “地址ID”

"Boss" - "Person.BossID" “老板” - “Person.BossID”

public Dictionary<string,string> GetForeignKeyProperties<DBType>()
{
    EntityType table = GetTableEntityType<DBType>();
    Dictionary<string, string> foreignKeys = new Dictionary<string, string>();

    foreach (NavigationProperty np in table.NavigationProperties)
    {
        var association = (np.ToEndMember.DeclaringType as AssociationType);
        var constraint = association.ReferentialConstraints.FirstOrDefault();



        if (constraint != null && constraint.ToRole.GetEntityType() == table)
            foreignKeys.Add(np.Name, constraint.ToProperties.First().Name);

        if (constraint != null && constraint.FromRole.GetEntityType() == table)
            foreignKeys.Add(np.Name, constraint.ToProperties.First().DeclaringType.Name+"."+constraint.ToProperties.First().Name);
    }

    return foreignKeys;
}

private EntityType GetTableEntityType<DBType>()
{
    return GetTableEntityType(typeof(DBType));
}

private EntityType GetTableEntityType(Type DBType)
{
    ObjectContext objContext = ((IObjectContextAdapter)this).ObjectContext;
    MetadataWorkspace workspace = objContext.MetadataWorkspace;
    EntityType table = workspace.GetEdmSpaceType((StructuralType)workspace.GetItem<EntityType>(DBType.FullName, DataSpace.OSpace)) as EntityType;
    return table;
}

Here's a method that returns key values of know entity objects: 这是一个返回已知实体对象的键值的方法:

IEnumerable<IDictionary<string,object>> GetKeyValues<T>(DbContext db, 
                                                        IEnumerable<T> entities)
    where T : class
{
    var oc = ((IObjectContextAdapter)db).ObjectContext;
    return entities.Select (e => oc.ObjectStateManager.GetObjectStateEntry(e))
                   .Select(objectStateEntry => objectStateEntry.EntityKey)
                   .Select(ek => ek.EntityKeyValues
                                   .ToDictionary (x => x.Key, y => y.Value));
}

This method uses the underlying ObjectContext API to obtain ObjectStateEntry objects that belong to each entity object. 此方法使用基础ObjectContext API来获取属于每个实体对象的ObjectStateEntry对象。 The EntityKey contains the key value(s) of an entity as a key-value pair. EntityKey包含实体的键值作为键值对。 (Entities with composite keys have more than one key value.) (具有复合键的实体具有多个键值。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何加载导航属性? - How can I load a property of a navigational property? 我可以将具有导航属性的EF类用作控件的数据源吗? - Can I use EF class with navigational property as a datasource for my control? 是否可以根据导航属性ID进行限制? - Is it possible to limit based on navigational property id's? 我如何模拟实体框架的导航财产情报? - How Do I Mock Entity Framework's Navigational Property Intelligence? 如何在不扩展到相关导航属性的情况下检索计算属性? - How can I retrieve a calculated property without expanding to related navigation properties? 如何对导航(子)属性进行排序? - How can I apply sorting on navigational (child) properties? 不能包含虚拟导航属性 - Can't include a virtual navigational property 查询相关集合是否具有任何条目,但没有导航属性 - Query if related collection has any entry, but without navigational property 首先 Enitify Framework 代码:使用所需的相关导航属性更新实体 - Enitify Framework code first: Updating Entity With required related navigational property 如何指定强类型导航属性包括 - How to specify strongly typed navigational property includes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM