簡體   English   中英

如何找到與導航屬性相關的Id屬性?

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

對於我正在使用Entity Framework的項目,我希望能夠枚舉給定對象實例的所有導航屬性(假設它是由EF生成的對象)。 從那里我想獲得每個導航屬性的相關Id屬性。

例如,如果我得到Person類的實例,我希望能夠找到它的名為Address and Boss的導航屬性。 對於那兩個導航屬性,我想“查找”名為AddressIdBossId的相關Id屬性。

我需要那些Id屬性,所以我可以在不具有相同外鍵但具有完全相同的ID的不同數據庫上運行查詢。

到目前為止,我已經想出了一種方法來獲取由EF生成的隨機對象實例的RelationshipManager 在調試時,我可以通過Manager的Relationships屬性獲取外鍵關系。 但我只能獲得導航屬性名稱。 所以我可以看到有一個FK_Person_Address與名為Address的導航屬性相關,但我找不到AddressId

所以我的問題是,我怎樣才能動態地(不知道Person類的布局)發現與Address相關的AddressId屬性?

我知道外鍵關系可能在關系的另一端有Id屬性( Boss指向Person而不是PersonBossId )。 在那種情況下,當我正在檢查一個Person實例時,我仍然想發現Boss有一個PersonId

這將為您提供一個字典,其中所有導航屬性為Key,所有相關屬性為Value(該值可能是其他實體的屬性)

將這些添加到您的DBContext類並調用db.GetForeignKeyProperties<Person>()

結果將是這樣的:

“地址” - “地址ID”

“老板” - “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;
}

這是一個返回已知實體對象的鍵值的方法:

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));
}

此方法使用基礎ObjectContext API來獲取屬於每個實體對象的ObjectStateEntry對象。 EntityKey包含實體的鍵值作為鍵值對。 (具有復合鍵的實體具有多個鍵值。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM