2011-05-01 153 views
9


我想要做的是將實體對象傳遞給方法並返回其中的所有屬性名稱。
我使用這個代碼把所有的道具名稱:如何獲取實體中所有屬性的名稱?

return classObject.GetType().GetProperties(); 

的問題是,這個代碼回報「的EntityKey」和「EntityState」爲屬性磨片我用它來與實體對象。
有什麼辦法可以做到嗎?

提前感謝名單

+1

因此,你是否得到了你需要的所有東西,加上「EntityKey」和「EntityState」,還是你唯一回來的那兩個? – 2011-05-01 20:47:25

+0

@Bala R:我得到的每件事加上我提到的 – Dabbas 2011-05-01 21:03:54

回答

22

你希望所有的直接屬性,但基本類型,而你的情況是EntityObject的不是性能:

var type = classObject.GetType(); 
//alternatively call out directly: typeof(EntityObject).GetProperties()... 
var basePropertyNames = type.BaseType.GetProperties().Select(x => x.Name); 
var props = type.GetProperties().Where(p => !basePropertyNames.Contains(p.Name)); 

此示例假設有一個基本類型(這對於DB來說就是這種情況),當不能保證時重構。

編輯從@馬特的評論:以上全部是不必要的,可以拍我的頭,沒有想到這一點 - 只要使用正確的綁定標誌:

return classObject.GetType().GetProperties(BindingFlags.DeclaredOnly | 
              BindingFlags.Public | 
              BindingFlags.Instance); 
+5

爲什麼不使用'classObject.GetType().GetProperties(BindingFlags.DeclaredOnly)'? – 2011-05-01 21:01:00

+4

@Matt:因爲我是一個id * ot -fixing我的回答 – BrokenGlass 2011-05-01 21:05:16

+2

和@Matt:謝謝你的答案。 @BrokenGlass:當我使用@ Marrs的修改後的代碼時,我得到了屬性,但也得到了一些我不想要的屬性,這就是導航屬性,所以我修改了一下代碼,現在它工作了: 'var basePropertyNames = classObject .GetType()。BaseType.GetProperties()。Select(x => x.Name); (p =>!basePropertyNames.Contains(p.Name)&&!p.PropertyType.IsClass).Select(x => x.Name);'返回類Object.GetType()。GetProperties 我不知道這是否適用於所有的實體。 – Dabbas 2011-05-01 21:27:19

1

正如BrokenGlass說,但要注意如果你需要性能,你想在循環中做到這一點。反思並不是一件快事。

如果您需要性能,您可能希望在您的基類中放入一個虛擬方法來檢索屬性作爲字符串或其他類型的數組,並覆蓋所有派生類中的屬性。這將是fastes的方法,但更多的編碼。

2

我有同樣的問題。我找到的解決方案是創建一個數組,其中包含要返回的屬性的名稱(我只需要一些)。在你的情況下,因爲跟蹤所有屬性會很費力,所以我會過濾EntityKeyEntityState的屬性並返回所有其他屬性。代碼將是這樣的:

public IEnumerable<PropertyInfo> GetProperties() 
{ 
    Type t = this.GetType(); 

    return t.GetProperties() 
     .Where(p => (p.Name != "EntityKey" && p.Name != "EntityState")) 
     .Select(p => p).ToList(); 
} 

不知道是否有更好的解決方案,但它會很好;)希望它有幫助!

7

也可能沒有反映:

using (var context = new ModelContainer()) 
{ 
    // Access CSDL 
    var container = context.MetadataWorkspace 
          .GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace); 
    // Access name of related set exposed on your context 
    var set = container.BaseEntitySets[context.YourEntitySet.EntitySet.Name]; 
    // Access all properties 
    var properties = set.ElementType.Members.Select(m => m.Name).ToList(); 
    // Access only keys 
    var keys = set.ElementType.KeyMembers.Select(m => m.Name).ToList(); 
} 

正如你可以看到你有機會獲得更多的則名。該示例顯示您現在可以將哪個屬性作爲關鍵字的一部分。如果直接訪問Members,則可以知道哪些屬性是標量,複雜類型或導航屬性。

所有信息已經加載,所以不需要反思。如果您想使用反射,請不要忘記僅使用一次(第一次需要它),然後存儲並重新使用收到的屬性名稱。反射速度很慢,所以每次需要名稱時使用它都是不好的做法。

相關問題