2011-05-01 120 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,则可以知道哪些属性是标量,复杂类型或导航属性。

所有信息已经加载,所以不需要反思。如果您想使用反射,请不要忘记仅使用一次(第一次需要它),然后存储并重新使用收到的属性名称。反射速度很慢,所以每次需要名称时使用它都是不好的做法。

相关问题