2009-09-10 7 views
14

Je souhaite générer automatiquement des instructions SQL à partir d'une instance de classe. La méthode doit ressembler à Update (object [] Properties, object PrimaryKeyProperty). La méthode fait partie d'une instance (class, base method - générique pour tout enfant). Tableau de propriétés est un tableau de propriétés de classe, qui sera utilisé dans mise à jour instruction. Les noms de propriété sont égaux aux noms des champs de table.Accès au nom ou aux attributs de la propriété C#

Le problème est que je ne peux pas obtenir les noms de propriété.

Existe-t-il une option pour obtenir un nom de propriété à l'intérieur de l'instance de classe? échantillon:

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" 

{ 

Je suis au courant de PropertyInfo, mais je ne sais pas chaud pour obtenir l'ID d'une propriété de tableau de GetProperties().

Une suggestion?

Répondre

7

Vous pouvez faire quelque chose comme ceci:

Type t = someInstance.getType(); 

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

pour obtenir tous les noms de propriétés pour le type de instance.

+1

Il ne veut pas tous les noms de propriété, seulement ceux spécifiques –

+1

Je ne sais pas que de mérite une downvote. La question dit, "est-il une option pour obtenir le nom de la propriété dans l'instance de classe?" J'ai montré une boucle qui traverse l'impression de tous les noms de propriété dans une instance de classe, mais il peut tous obtenir ceux qu'il veut mettre à jour dans un tableau qu'il passe à la procédure de mise à jour. Je ne vois pas quel est le problème. –

1

Puisque vous avez déjà un handle explicite à la propriété spécifique que vous voulez, vous connaissez le nom - pouvez-vous simplement le taper?

+0

Je pense qu'il veut que le code fonctionne également pour les classes dérivées, il doit donc utiliser la réflexion. –

+0

L'idée principale n'est pas de dupliquer les noms. Donc, quand une classe (avec des attributs) est écrite, je reçois une génération de table automatique, des instructions CRUD et * Intellisense *. – FrenkR

28

Just wrote an implementation of this pour une présentation sur lambdas pour notre groupe d'utilisateurs mardi dernier.

  • Vous pouvez faire

    membresde <animaux> .GetName (x => x.Status)

  • Ou

    var a = new animal() a.MemberName (x => x.État)

le 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

Salut George, votre solution ne fonctionne pas pour les membres Lambda imbriqués de .GetName (x => x.Gender.Text) devrait donner "Gender.Text", pas seulement "Text". –

+0

@Stef, c'est correct. x.Gender.Text n'est pas un accesseur membre. Vérifiez la mise en œuvre cependant, il devrait être relativement facile de le faire détecter toute une arborescence de syntaxe et recurse à plusieurs reprises –

+0

la réponse de LukeH à http://stackoverflow.com/questions/3049825/given-a-member-access-lambda-expression -convert-it-a-specific-string-represen est exactement ce dont j'ai besoin. –

2

Vous pouvez obtenir le nom (je suppose que ce que vous vouliez dire par ID) d'une propriété à l'aide PropertyInfo.Name. Juste boucle à travers les PropertyInfo [] retour de typeof (className) .GetProperties()

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

Je voudrais pouvoir vous donner +10 pour cela :) –

1

Disons que (à partir du premier échantillon, la mise à jour de la méthode d'une 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} et {iMyKey} sont les valeurs de propriété d'une instance de classe.

Ainsi, le problème est comment obtenir le nom de propriété (réflexion) à partir d'une propriété sans utiliser les noms de propriétés en tant que chaînes (pour éviter les fautes de frappe).

10

J'ai trouvé une solution parfaite dans This Post

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

Et puis pour l'utilisation:

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

fonctionne comme un charme

1

pas 100% sûr si cela vous obtiendrez ce que vous Recherchez, cela va chercher toutes les propriétés avec l'attribut [Column] dans votre classe: Dans le datacontext j'ai:

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

Récupérer la table colonne noms qui sont des propriétés à l'intérieur de la 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); 
Questions connexes