[英]How can I find the Id property or properties related to a navigational property?
對於我正在使用Entity Framework的項目,我希望能夠枚舉給定對象實例的所有導航屬性(假設它是由EF生成的對象)。 從那里我想獲得每個導航屬性的相關Id屬性。
例如,如果我得到Person
類的實例,我希望能夠找到它的名為Address
and Boss
的導航屬性。 對於那兩個導航屬性,我想“查找”名為AddressId
和BossId
的相關Id屬性。
我需要那些Id屬性,所以我可以在不具有相同外鍵但具有完全相同的ID的不同數據庫上運行查詢。
到目前為止,我已經想出了一種方法來獲取由EF生成的隨機對象實例的RelationshipManager 。 在調試時,我可以通過Manager的Relationships
屬性獲取外鍵關系。 但我只能獲得導航屬性名稱。 所以我可以看到有一個FK_Person_Address
與名為Address
的導航屬性相關,但我找不到AddressId
。
所以我的問題是,我怎樣才能動態地(不知道Person
類的布局)發現與Address
相關的AddressId
屬性?
我知道外鍵關系可能在關系的另一端有Id屬性( Boss
指向Person
而不是Person
有BossId
)。 在那種情況下,當我正在檢查一個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.