2009-09-10 14 views
14

Me gustaría generar automáticamente sentencias SQL a partir de una instancia de clase. El método debe verse como Actualizar (objeto [] Propiedades, objeto PrimaryKeyProperty). El método es parte de una instancia (clase, método básico, genérico para cualquier niño). Matriz de propiedades es una matriz de propiedades de clase, que se usará en la declaración . Los nombres de las propiedades son iguales a los nombres de los campos de la tabla.Acceso al nombre o atributos de la propiedad C#

El problema es que no puedo obtener los nombres de las propiedades.

¿Hay alguna opción para obtener un nombre de propiedad dentro de la instancia de la clase? muestra:

public class MyClass { 
public int iMyProperty { get; set; } 
public string cMyProperty2 { get; set; } 
{ 

main() { 
MyClass _main = new MyClass(); 

_main.iMyProperty.*PropertyName* // should return string "iMyProperty" 

{ 

Soy consciente de PropertyInfo, pero no sé caliente para obtener el ID de una propiedad de GetProperties() matriz.

¿Alguna sugerencia?

Respuesta

7

se puede hacer algo como esto:

Type t = someInstance.getType(); 

foreach (MemberInfo mi in t.GetMembers()) 
{ 
    if (mi.MemberType == MemberTypes.Property) 
    { 
     Console.WriteLine(mi.Name); 
    } 
} 

para obtener todos los nombres de propiedades para instance 's tipo.

+1

que no quiere que todos los nombres de propiedad, sólo los específicos –

+1

No estoy seguro de que merece una Downvote. La pregunta dice, "¿hay alguna opción para obtener el nombre de la propiedad dentro de la instancia de la clase?" He mostrado un ciclo que pasa imprimiendo * todos * los nombres de propiedad en una instancia de clase, pero todos pueden obtener los que quiere actualizar en una matriz que pasa al procedimiento de actualización. No veo cuál es el problema. –

1

Dado que ya tiene un descriptor explícito de la propiedad específica que desea, conoce el nombre. ¿Puede escribirlo?

+0

Creo que él también quiere que el código funcione para las clases derivadas, por lo que necesita usar el reflejo. –

+0

La idea principal no es duplicar nombres. Entonces, cuando se escribe una clase (con atributos) obtengo una generación automática de tablas, sentencias CRUD y * Intellisense *. – FrenkR

28

Just wrote an implementation of this para una presentación sobre lambdas para nuestro grupo de usuarios el martes pasado.

  • Usted puede hacer

    MembersOf <Animal> .GetName (x => x.Status)

  • O

    var a = new Animal() a.MemberName (x => x.Status)

la c oda:

public static class MembersOf<T> { 
    public static string GetName<R>(Expression<Func<T,R>> expr) { 
     var node = expr.Body as MemberExpression; 
     if (object.ReferenceEquals(null, node)) 
      throw new InvalidOperationException("Expression must be of member access"); 
     return node.Member.Name; 
    } 
} 
+0

Hola George, tu solución no funciona para los archivos anidados de Lambda como MembersOf . GetName (x => x.Gender.Text) debería dar "Gender.Text", no solo "Text". –

+0

@Stef, eso es correcto. x.Gender.Text no es un usuario de acceso. Sin embargo, compruebe la implementación, debería ser relativamente fácil hacer que detecte un árbol de sintaxis completo y recurse repetidamente –

+0

la respuesta de LukeH en http://stackoverflow.com/questions/3049825/given-a-member-access-lambda-expression -convertirlo en un representante de cadena específica es exactamente lo que necesito. –

2

Usted puede obtener el nombre (supongo que eso es lo que entiende por ID) de un establecimiento a través de PropertyInfo.Name. Simplemente bucle a través de los [] devuelto al typeof .GetProperties PropertyInfo (className)()

foreach (PropertyInfo info in typeof(MyClass).GetProperties()) 
{ 
    string name = info.Name; 
    // use name here 
} 
+0

Ojalá pudiera darte +10 por esto :) –

1

Digamos (de la primera muestra, método update de una clase MyClass):

public class MyClass { 

public int iMyStatusProperty { get; set; } 
public int iMyKey { get; set; } 

public int UpdateStatusProperty(int iValue){ 
this.iMyStatusProperty = iValue; 
return _Update(new[iMyStatusProperty ], iMyKey); // this should generate SQL: "UPDATE MyClass set iMyStatusProperty = {iMyStatusProperty} where iMyKey = {iMyKey}" 
} 

{iMyStatusProperty} y {iMyKey} son valores de propiedad de una instancia de clase.

Por lo tanto, el problema es cómo obtener el nombre de propiedad (reflejo) desde una propiedad sin utilizar nombres de propiedades como cadenas (para evitar los errores tipográficos del nombre de campo).

10

he encontrado una solución perfecta en This Post

public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression) 
{ 
    return (propertyExpression.Body as MemberExpression).Member.Name; 
} 

Y luego para el uso:

var propertyName = GetPropertyName(
() => myObject.AProperty); // returns "AProperty" 

funciona como un encanto

1

No es 100% seguro de si esto va a conseguir lo que Estoy buscando, esto obtendrá todas las propiedades con el atributo [Columna] dentro de su clase: En el contexto de datos tengo:

public ReadOnlyCollection<MetaDataMember> ColumnNames<TEntity>() 
    { 
     return this.Mapping.MappingSource.GetModel(typeof(DataContext)).GetMetaType(typeof(TEntity)).DataMembers; 
    } 

Obtención de las columnas de la tabla nombres que son propiedades dentro de la clase:

 MyDataContext db = GetDataContext(); 
     var allColumnPropertyNames = db.ColumnNames<Animal>().Where(n => n.Member.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false).FirstOrDefault() != null).Select(n => n.Name); 
Cuestiones relacionadas