Десериализовать анонимный тип в динамический - PullRequest
1 голос
/ 22 сентября 2011

У меня есть приложение, которое содержит бизнес-объект, который называется «Задача».У этой сущности есть фиксированный набор свойств, но она также может вести себя как экспансия.

Итак, ее схема выглядит следующим образом:

namespace RavenResearch
{
    public class Task
    {
        public Guid TaskId { get; set; }
        public DateTime CreatedDate { get; set; }
        public dynamic DynamicProperties { get; set; }
    }
}

Когда она хранится в RavenDB, онаlook liks this

{
  "TaskId": "9cac592f-98ec-4fda-a823-e5402736078e",
  "CreatedDate": "2011-09-22T10:25:35.2701544+12:00",
  "DynamicProperties": {
    "$type": "<>f__AnonymousType0`2[[System.Int32, mscorlib],[System.String, mscorlib]], RavenResearch",
    "MatterNumber": 0,
    "CustomerNumber": "37"
  }
}

Конечно, когда я пытаюсь запросить это хранилище данных из ДРУГОЙ программы, он пытается найти анонимный тип, содержащий int и строку.Эта другая программа - EXE, которая изначально сохранила документ - я не хочу ссылаться на это.

Каков наилучший способ извлечь динамические свойства?Моя цель - иметь возможность запрашивать список объектов Task из Raven и передавать их в Xaml для рендеринга в пользовательском интерфейсе, поэтому привязка данных к Expando так привлекательна для меня, что свойства не должны быть известны во время компиляции.

Я создаю экземпляры (для хранения в Raven) с такими утверждениями

new RavenResearch.Task()
{
    TaskId = Guid.NewGuid(),
    CreatedDate = DateTime.Now,
    DynamicProperties = new 
    {
        MatterNumber = 0,
        CustomerNumber = "37"
    }
}

@ Джейкоб: Я бы потерял всю информацию о типах динамических свойств, если бы использовал словарь - однако яможет сделать что-то вроде этого:

public class Task
{
    public Guid TaskId { get; set; }
    public DateTime CreatedDate { get; set; }
    public Dictionary<string, SimpleValue> DynamicProperties { get; set; }
}

public abstract class SimpleValue
{

}

public class SimpleValue<T> : SimpleValue
{
    public T Value
    { get; set; }

    public SimpleValue(T value)
    {
        this.Value = value;
    }
}

Ответы [ 2 ]

3 голосов
/ 22 сентября 2011

Помните, что во время выполнения динамический объект - это просто объект, у нас нет возможности узнать, что вы на самом деле имели в виду. Возможно, вам лучше использовать RavenJObject вместо этого. Это был бы более естественный способ работы с динамическими данными, и он сохранил бы информацию о типе

1 голос
/ 22 сентября 2011

Возможно, лучше избегать использования dynamic в этом случае. Если вместо этого вы используете Dictionary<string, object>, создание Task не будет слишком ужасным:

new RavenResearch.Task {
    TaskId = Guid.NewGuid(),
    CreatedDate = DateTime.Now,
    DynamicProperties = new Dictionary<string, object> {
        { "MatterNumber", 0 },
        { "CustomerNumber", "37" } 
    }
}
...