2011-05-01 15 views
9


Lo que trato de hacer es pasar un objeto entidad al método y devolver todos los nombres de las propiedades en él.
Estoy usando este código para obtener todos los nombres de los apoyos:¿Cómo obtener todos los nombres de propiedades en una entidad?

return classObject.GetType().GetProperties(); 

El problema es que este código de retorno "EntityKey" y "EntityState" como propiedades cuando planees lo uso con la Entidad objeto.
¿Hay alguna manera de hacerlo?

Gracias de antemano

+1

Entonces, ¿está recibiendo todo lo que necesita además de "EntityKey" y "EntityState" o son esos dos los únicos que recibirá? –

+0

@Bala R: obtengo todo más lo que mencioné – Dabbas

Respuesta

22

Quiere todas las propiedades directas, pero no las propiedades del tipo de base, que en su caso es 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)); 

este ejemplo se supone que hay un tipo de base (cuál es el caso para DB primero), refactor cuando eso no se garantiza.

Editar de @ comentarios de Matt: Todo lo anterior es innecesaria, podría imponer mi cabeza por no haber pensado en esto - sólo tiene que utilizar la unión adecuados banderas:

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

¿Por qué no utilizar 'classObject.GetType(). GetProperties (BindingFlags.DeclaredOnly)'? –

+4

@Matt: porque soy id * ot -fixing my answer – BrokenGlass

+2

y @Matt: gracias por las respuestas. @BrokenGlass: cuando utilicé @ código modificado de Marrs que consiguen las propiedades pero también reciben algunas propiedades que no quiero, que es las propiedades de navegación por lo que modificó el código de poco y funcionó por ahora: 'var = basePropertyNames classObject .GetType(). BaseType.GetProperties(). Seleccione (x => x.Name); retorno classObject.GetType() GetProperties() Donde (p => basePropertyNames.Contains (p.Name) && p.PropertyType.IsClass!) .Elija (x => x.Name);..' No sé si esto funcionará para todas las entidades o no ... – Dabbas

1

Según lo indicado por BrokenGlass pero ojo si necesita rendimiento y desea hacerlo en bucles. La reflexión no es una cosa rápida.

Si necesita rendimiento, puede poner un método virtual en su clase base para recuperar las propiedades como una matriz de cadenas o lo que sea, y anular eso en todas las clases derivadas. Este sería el enfoque de ayuno, pero con más codificación.

2

Tuve el mismo problema. La solución que encontré fue crear una matriz con el nombre de las propiedades para devolver (solo necesito algunas). En su caso, dado que puede ser laborioso realizar un seguimiento de todas las propiedades, filtrar las propiedades EntityKey y EntityState y devolver todas las demás. El código sería algo como esto:

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

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

No sé si hay una solución mejor, pero sería bueno;) Espero que ayude!

7

También es posible sin reflexión:

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

Como se puede ver que tiene acceso a mucho más que nombres. El ejemplo muestra que ahora puede qué propiedad es parte de la clave. Si accede directamente al Members, puede saber qué propiedad es escalar, de tipo complejo o de navegación.

Toda la información ya está cargada, por lo que no hay necesidad de reflexión. Si desea utilizar la reflexión, no olvide utilizarla solo una vez (la primera vez que la necesite) y luego almacenar y reutilizar los nombres de las propiedades recibidas. La reflexión es lenta, así que usarla cada vez que necesitas nombres es una mala práctica.

Cuestiones relacionadas