2015-09-16 4 views
1

Я пытаюсь создать динамический ExpandoObject. Я столкнулся с определенной проблемой.C# - Добавление объектов динамически (добавление динамических имен свойств)

Как я не знаю, что название этих различных свойств в моих объектах должно быть, я не могу сделать так:

var list = new ArrayList(); 

var obj = new ExpandoObject(); 
obj.ID = 1, 
obj.Product = "Pie", 
obj.Days = 1, 
obj.QTY = 65 

list.Add(obj); 

Позвольте мне объяснить мою ситуацию: Я хотел бы получить данные из случайная БД (я не знаю, какой, но строя строку соединения из информации, которую я получаю от пользовательского интерфейса), поэтому я не знаю, какие данные мне нужно получить. Это может быть пример таблицы DB

ТАБЛИЦА Продажа

  • ID: Int,
  • продукта: NVARCHAR (100),
  • Дни: Int,
  • КОЛ: BigInt

Это может быть другой пример:

ТАБЛИЦА Foobar

  • Id: ИНТ,
  • Дни: ИНТ
  • QTY: BIGINT
  • PRODUCT_ID: INT
  • department_id: INT

Как вы видите, я не знаю, как выглядит БД (это 100% анонимно, поэтому оно должно быть на 100% динамическим), а данные, которые я хочу вернуть, должны выглядеть как хорошо построенный JSON, например:

[ 
    { 
    "ID": 1, 
    "Product": "Pie" 
    "Days": 1, 
    "QTY": 65 
    }, 
    { 
    "ID": 2, 
    "Product": "Melons" 
    "Days": 5, 
    "QTY": 12 
    } 
] 

Или, с другой пример:

[ 
    { 
    "ID": 1, 
    "Days": 2, 
    "QTY": 56, 
    "Product_Id": 5, 
    "Department_Id": 2 
    } 
    { 
    "ID": 2, 
    "Days": 6, 
    "QTY": 12, 
    "Product_Id": 2, 
    "Department_Id": 5 
    } 
] 

Я пробовал работать с этими ExpandoObject с, но не могу заставить его работать, так как я не могу делать то, что показано в наверху этого вопроса (Я не знаю названий свойств). Есть ли способ для меня, чтобы сказать что-то вроде:

var obj = new ExpandoObject(); 
var propName = "Product"; 

var obj.propName = "Pie" 

Console.WriteLine("Let's print!: " + obj.Product); 

//OUTPUT 
Let's print!: Pie 

Кто-нибудь есть решение, OG просто руководство к структуре, которая может решить эту ситуацию?

+0

какой язык вы используете? вы отметили C#, но часть вашего кода - Java (i.e System.out.printline). У .NET этого нет. –

+0

Я не копировал вставить код. Я просто не могу вспомнить, как это называется на C#. Это чистый C# и ничего больше. Мои извинения. Будет исправлен – Detilium

+0

возможный дубликат [установка C#/получение свойств класса по имени строки] (http://stackoverflow.com/questions/10283206/c-sharp-setting-getting-the-class-properties-by-string-name) – GSerg

ответ

3

Вместо того, чтобы создавать ExpandoObject или какой-либо другой динамический тип, вы можете создать List<Dictionary<string, object>>, где каждый Dictionary<string, object> содержит пары имени/значения, которые вы хотите сериализовать.Затем сериализации в JSON с помощью Json.NET (или JavaScriptSerializer, хотя это менее гибким):

 var list = new List<Dictionary<string, object>>(); 

     // Build a dictionary entry using a dictionary initializer: https://msdn.microsoft.com/en-us/library/bb531208.aspx 
     list.Add(new Dictionary<string, object> { { "ID", 1 }, {"Product", "Pie"}, {"Days", 1}, {"QTY", 65} }); 

     // Build a dictionary entry incrementally 
     // See https://msdn.microsoft.com/en-us/library/xfhwa508%28v=vs.110%29.aspx 
     var dict = new Dictionary<string, object>(); 
     dict["ID"] = 2; 
     dict["Product"] = "Melons"; 
     dict["Days"] = 5; 
     dict["QTY"] = 12; 
     list.Add(dict); 

     Console.WriteLine(JsonConvert.SerializeObject(list, Formatting.Indented)); 
     Console.WriteLine(new JavaScriptSerializer().Serialize(list)); 

Первые выходы:

[ 
    { 
    "ID": 1, 
    "Product": "Pie", 
    "Days": 1, 
    "QTY": 65 
    }, 
    { 
    "ID": 2, 
    "Product": "Melons", 
    "Days": 5, 
    "QTY": 12 
    } 
] 

втором выводит его без отступа:

[{"ID":1,"Product":"Pie","Days":1,"QTY":65},{"ID":2,"Product":"Melons","Days":5,"QTY":12}] 
+0

Не будет работать в моем случае, так как у меня нет всех доступных значений, но мне нужно их пропустить. Не могли бы вы привести пример? 'var valueList = allRowValues' и' var clumn = allClumnNames' (Работа над редактированием основного вопроса) – Detilium

+0

Словари были бы бесполезны, если вы не смогли [добавить] (https://msdn.microsoft.com/en-us /library/k7z0zy8k%28v=vs.110%29.aspx) после того, как вы создали их @Detilium. – GSerg

+0

@dbc почему-то мой Json выглядит так: '[{\" ID \ ": 1, \" Product \ ": \" Honning \ ", \" Days \ ": 1, \" QTY \ ": 65 }] ' – Detilium

0

Как вы можете видеть здесь ExpandoObject Class, то ExpandoObject реализует IDictionary<string, object>, так что вы можете использовать этот факт как

IDictionary<string, object> obj = new ExpandoObject(); 
var propName = "Product"; 
obj[propName] = "Pie" 
Console.WriteLine("Let's print!: " + obj[propName]); 
// Verify it's working 
Console.WriteLine("Let's print again!: " + ((dynamic)obj).Product); 
-1

первой части, прочитать this blog post на # команды C тщательно.

Позволяет увидеть ваш код

var obj = new ExpandoObject(); 
var propName = "Product"; 

var obj.propName = "Pie" 

Console.WriteLine("Let's print!: " + obj.Product); 

//OUTPUT 
Let's print!: Pie 

В своем коде вы используете var obj = new ExpandoObject();, так что вы создаете статически типизированный объект типа ExpandableObject. В блоге они специально взывать

Я не писал ExpandoObject контакт = новый ExpandoObject(), потому что если я сделал контакт будет статически типизированный объект типа ExpandoObject. И, конечно, статически типизированные переменные не могут добавлять элементы во время выполнения. Таким образом, я использовал новое динамическое ключевое слово вместо объявления типа, а так ExpandoObject поддерживает динамические операции, код работает

Так что, если вы переписать код, чтобы использовать dynamic obj и добавить динамические свойства как свойства, он должен работать!

Но для вашего конкретного случая использования вам лучше использовать словари, как предложено выше, @dbc

dynamic obj = new ExpandoObject(); 
obj.Product= "Pie"  
Console.WriteLine("Let's print!: " + obj.Product);  
//OUTPUT 
Let's print!: Pie 
+0

Ни его, ни ваш код не будут работать. Они даже не собираются. Когда вы их компилируете, удаляя ненужный «var» и добавляя отсутствующий ';', вы увидите, что он не делает то, что вы ожидаете, и выдает исключение вместо печати «Pie», потому что этот код добавляет свойство 'propName' на 'obj', а не на свойство' Product'. – GSerg

+0

c ** p, я заметил только статический тип в качестве проблемы. отредактирует мой ответ, чтобы исправить их. У меня нет доступа к Visual Studio на данный момент, пришел к SO для чего-то другого, увидел это! – Adarsha

1

dynamic Используйте, затем отливал в IDictionary<string, object> Переберите свойства:

dynamic obj = new ExpandoObject(); 
obj.Product = "Pie"; 
obj.Quantity = 2; 

// Loop through all added properties  
foreach(var prop in (IDictionary<string, object>)obj) 
{ 
    Console.WriteLine(prop.Key + " : " + prop.Value); 
} 

I 've сделал скрипку: https://dotnetfiddle.net/yFLy2u

Теперь это решение для вашего q uestion ... другие ответы, такие как @ dbc, могут быть лучше подходят для проблемы (это не вопрос, действительно)

0

Пока я писал ответ, я вижу, что у вас уже есть правильный ответ. Вы можете использовать Dictionary<string, onject> или даже Tuple.

Но согласно вашему первоначальному вопросу вы хотели бы добавить свойства динамически. Для этого вы можете обратиться к другому ответу, используя ExpandoObject. Это то же самое решение (используя ExpandoObject для динамического добавления свойств) с классами, аналогичными вашему коду.

//example classes 
public class DictKey 
{ 
    public string DisplayName { get; set; } 
    public DictKey(string name) { DisplayName = name; } 
} 

public class DictValue 
{ 
    public int ColumnIndex { get; set; } 
    public DictValue(int idx) { ColumnIndex = idx; } 
} 

//utility method 
public static IDictionary<string, object> GetExpando(KeyValuePair<DictKey, List<DictValue>> dictPair) 
{ 
    IDictionary<string, object> dynamicObject = new ExpandoObject(); 
    dynamicObject["Station"] = dictPair.Key.DisplayName; 
    foreach (var item in dictPair.Value) 
    { 
     dynamicObject["Month" + (item.ColumnIndex + 1)] = item; 
    } 
    return dynamicObject; 
} 

Ans Пример использования:

var dictionaryByMonth = new Dictionary<DictKey, List<DictValue>>(); 
dictionaryByMonth.Add(new DictKey("Set1"), new List<DictValue> { new DictValue(0), new DictValue(2), new DictValue(4), new DictValue(6), new DictValue(8) }); 
dictionaryByMonth.Add(new DictKey("Set2"), new List<DictValue> { new DictValue(1), new DictValue(2), new DictValue(5), new DictValue(6), new DictValue(11) }); 

var rowsByMonth = dictionaryByMonth.Select(item => GetExpando(item));