it-swarm.com.de

Gibt es eine einfache Möglichkeit, Objekteigenschaften in ein Wörterbuch <string, string> zu konvertieren

Ich habe ein Datenbankobjekt (eine Zeile), das viele Eigenschaften (Spalten) aufweist, die die Felder bilden (asp: textbox, asp: dropdownlist usw.). Ich möchte dieses Objekt und seine Eigenschaften in eine Wörterbuchzuordnung umwandeln, um die Iteration zu erleichtern.

Beispiel:

Dictionary<string, string> FD = new Dictionary<string,string>();
FD["name"] = data.name;
FD["age"] = data.age;
FD["occupation"] = data.occupation;
FD["email"] = data.email;
..........

Wie mache ich das einfach, ohne die verschiedenen Hunderte von Eigenschaften manuell einzugeben?

Hinweis: FD-Wörterbuchindizes entsprechen den Datenbankspaltennamen.

28
Dexter

Angenommen, dass data ein Objekt ist und Sie die öffentlichen Eigenschaften in ein Wörterbuch einfügen möchten, können Sie Folgendes versuchen:

Original - hier aus historischen Gründen (2012) :

Dictionary<string, string> FD = (from x in data.GetType().GetProperties() select x)
    .ToDictionary (x => x.Name, x => (x.GetGetMethod().Invoke (data, null) == null ? "" : x.GetGetMethod().Invoke (data, null).ToString()));

Aktualisiert (2017) :

Dictionary<string, string> dictionary = data.GetType().GetProperties()
    .ToDictionary(x => x.Name, x => x.GetValue(data)?.ToString() ?? "");
59
Yahia

Die HtmlHelper-Klasse ermöglicht eine Konvertierung des Anonymouns-Objekts in RouteValueDictonary. Ich denke, Sie könnten für jeden Wert ein .ToString () verwenden, um die Zeichenfolgenwiederholung zu erhalten:

 var linkAttributes = System.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes(linkHtmlAttributes);

Der Nachteil ist, dass dieser Teil des ASP.NET MVC Framework ist. Bei Verwendung eines .NET Reflector lautet der Code innerhalb der Methode wie folgt:

public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes)
{
   RouteValueDictionary dictionary = new RouteValueDictionary();
  if (htmlAttributes != null)
  {
     foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes))
     {
            dictionary.Add(descriptor.Name.Replace('_', '-'), descriptor.GetValue(htmlAttributes));
       }
 }
    return dictionary;
 }

Sie werden sehen, dass dieser Code mit der Antwort identisch ist, die Yahia Ihnen gegeben hat, und seine Antwort enthält ein Dictonary <string, string>. Mit dem reflektierten Code, den ich Ihnen gegeben habe, könnten Sie ein RouteValueDictionary leicht in Dictonary <string, string> konvertieren, aber Yahias Antwort ist ein Einzeiler.

EDIT - Ich habe den Code für eine mögliche Konvertierungsmethode hinzugefügt:

EDIT 2 - Ich habe den Code zur Nullprüfung hinzugefügt und String.Format für den Stringwert verwendet.

    public static Dictionary<string, string> ObjectToDictionary(object value)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        if (value != null)
        {
            foreach (System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(value))
            {
                if(descriptor != null && descriptor.Name != null)
                {
                     object propValue = descriptor.GetValue(value);
                     if(propValue != null)
                          dictionary.Add(descriptor.Name,String.Format("{0}",propValue));
            }
        }
        return dictionary;
    }

Und um von einem Wörterbuch zu einem Objekt zu wechseln http://automapper.org/ , das in diesem Thread vorgeschlagen wurde Wörterbuch in ein anonymes Objekt konvertieren

10
Nick Bork
var myDict = myObj.ToDictionary(); //returns all public fields & properties

.

public static class MyExtensions
{
    public static Dictionary<string, object> ToDictionary(this object myObj)
    {
        return myObj.GetType()
            .GetProperties()
            .Select(pi => new { Name = pi.Name, Value = pi.GetValue(myObj, null) })
            .Union( 
                myObj.GetType()
                .GetFields()
                .Select(fi => new { Name = fi.Name, Value = fi.GetValue(myObj) })
             )
            .ToDictionary(ks => ks.Name, vs => vs.Value);
    }
}
9
L.B

Schauen Sie sich System.ComponentModel.TypeDescriptor.GetProperties( ... ) an. Auf diese Weise funktionieren die normalen Datenbindungsbits. Es wird Reflektion verwenden und eine Sammlung von Eigenschaftsdeskriptoren zurückgeben (die Sie zum Abrufen der Werte verwenden können). Sie können diese Deskriptoren für Performace anpassen, indem Sie ICustomTypeDescriptor implementieren.

0
MaLio