2009-09-10 27 views
14

Vorrei generare automaticamente le istruzioni SQL da un'istanza di classe. Il metodo dovrebbe apparire come Aggiorna (oggetto [] Proprietà, oggetto PrimaryKeyProperty). Il metodo è parte di un'istanza (classe, metodo base - generico per ogni bambino). La matrice di proprietà è una matrice di proprietà di classe, che verranno utilizzate nell'istruzione aggiornamento. I nomi delle proprietà sono uguali ai nomi dei campi della tabella.Accesso C# nome proprietà o attributi

Il problema è che non riesco a ottenere i nomi di proprietà.

C'è qualche possibilità di ottenere un nome di proprietà all'interno di un'istanza di classe? campione:

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" 

{ 

Sono consapevole del PropertyInfo, ma non so a caldo per ottenere l'ID di un immobile da GetProperties() array.

Qualche suggerimento?

risposta

7

si può fare qualcosa di simile:

Type t = someInstance.getType(); 

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

per ottenere tutti i nomi di proprietà per il tipo di instance s'.

+1

lui non vuole tutti i nomi di proprietà, solo quelli specifici –

+1

Non sono sicuro che merita una downvote. La domanda dice: "C'è qualche opzione per ottenere il nome della proprietà all'interno dell'istanza della classe?" Ho mostrato un ciclo che stampa tutti i nomi delle proprietà in un'istanza di classe, ma può ottenere tutti quelli che desidera aggiornare in un array che passa alla procedura di aggiornamento. Non vedo quale sia il problema. –

1

Dal momento che si dispone già di una maniglia esplicito alla proprietà specifico che si desidera, si conosce il nome - si può semplicemente digitare?

+0

Penso che voglia che il codice funzioni anche per le classi derivate, quindi ha bisogno di usare la riflessione. –

+0

L'idea principale non è quella di duplicare i nomi. Quindi, quando viene scritta una classe (con attributi) ottengo una generazione automatica di tabelle, istruzioni CRUD e * Intellisense *. – FrenkR

28

Just wrote an implementation of this per una presentazione su lambda per il nostro gruppo di utenti Martedì scorso.

  • Si può fare

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

  • O

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

il c ode:

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

Ciao George, la tua soluzione non funziona per i membri di Lambda nidificati come.GetName (x => x.Gender.Text) dovrebbe dare "Gender.Text", non solo "Testo". –

+0

@Stef, è corretto. x.Gender.Text non è un utente accessor. Controllare l'implementazione, tuttavia, dovrebbe essere relativamente facile far rilevare un intero albero di sintassi e recidare ripetutamente –

+0

la risposta di LukeH all'indirizzo http://stackoverflow.com/questions/3049825/given-a-member-access-lambda-expression -convert-it-to-a-specific-string-represen è esattamente ciò di cui ho bisogno. –

2

È possibile ottenere il nome (suppongo che è ciò che si intende per ID) di una proprietà utilizzando PropertyInfo.Name. Basta scorrere le tornati da typeof .GetProperties PropertyInfo [] (className)()

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

Vorrei poterti dare +10 per questo :) –

1

Diciamo (dal primo campione, metodo di aggiornamento di una classe 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} e {iMyKey} sono valori di proprietà di un'istanza di classe.

Quindi, il problema è come ottenere nome della proprietà (riflessione) da una proprietà senza utilizzare nomi delle proprietà come stringhe (per evitare errori di battitura di nomi di campo).

10

ho trovato una soluzione perfetta in This Post

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

E poi per l'utilizzo:

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

funziona come un fascino

1

non al 100% sicuro se questo sarà ottenere ciò che Stai cercando, questo recupererà tutte le proprietà con l'attributo [Column] all'interno della tua classe: Nel datacontext ho:

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

Recupero la tabella delle colonne-nomi che sono le proprietà all'interno della classe:

 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); 
Problemi correlati