Преобразование кадра данных Deedle в C # список пользовательского класса - PullRequest
0 голосов
/ 18 февраля 2019

Я получаю данные из внешнего API в качестве фрейма данных Deedle.Мне нужно взять эти данные и преобразовать их в список пользовательских классов для вставки в базу данных через Entity Framework.

Может ли кто-нибудь указать мне правильное направление?Я раньше не использовал Deedle, и у меня возникают проблемы с поиском лучшего способа извлечения данных.

Пользовательский объект, который мне нужно заполнить, выглядит следующим образом:

public class FrameData
{
    public string SecurityId { get; set; }
    public string FieldName { get; set; }
    public DateTime Date { set; get; }
    public decimal value { get; set; }
}

Спасибо, Ник

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

То, что сказал @Tomas Petricek, является хорошим примером, но, имея много разных классов, это может стать проблемой.

Итак, здесь я сделал пример, как динамически преобразовать его в определенный класс и использоватьатрибут для сопоставления между свойством и индексом столбца.

// Mapp a key to an index
public class IndexAttribute: Attribute(){
public int Index { get; private set; }
public IndexAttribute(int index){

Index = index;
}

}

public class FrameData
{
    [IndexAttribute(0)]
    public string SecurityId { get; set; }
    [IndexAttribute(3)]
    public string FieldName { get; set; }
    [IndexAttribute(2)]
    public DateTime Date { set; get; }
    [IndexAttribute(1)]
    public decimal value { get; set; }
}

// create a class the convert the frame to class

public static List<T> Convert<T>(this DataTable data) where T: class
{
  var list = new List<T>();
  foreach(var row in data.Rows){
   object item = Activator.CreateInstance(typeof(T));
   var props = typeof(T).GetProperties();
   foreach(var p in props){
    var index = p.GetCustomAttribute<IndexAttribute>()?.Index ?? -1;
    if (index< 0)
       continue;
       
      if (table.Columns.length > index) // if the index exist
      {
        var value = row[index]; // get the value.
        if (value == null)
         continue; // ignore null value
        if (prop.PropertyType == typeof(string))
         prop.SetValue(item, value.ToString());
       if (prop.PropertyType == typeof(DateTime))
          prop.SetValue(item, DateTime.Parse(value.ToString()));
          
        // .. now check for decimal, int etc
      }
    }
    list.Add(item);
  }
  return list;
}

And now all you need is to call the function

List<Person> persons = df.Convert<Person>(); // that all
0 голосов
/ 18 февраля 2019

Есть много способов получить данные из фрейма Deedle.Позволяет ли Entity Framework использовать интерфейсы?Если это так, то есть хорошая функция GetRowsAs, которая позволяет вам сделать это:

// Given a simple Person interface
public interface Person {
  int Age { get; }
  string Name{ get; }
}

// And a sample data frame with some data
Frame<int, string> df = Frame.FromValues(new[] {
    Tuple.Create(1, "Name", (object) "One"),
    Tuple.Create(2, "Name", (object) "Two"),
    Tuple.Create(1, "Age", (object) 42),
    Tuple.Create(2, "Age", (object) 21)
  });

// You can get an array of rows using 
var rows = df.GetRowsAs<Person>();

Если Entity Framework не может обрабатывать интерфейсы, тогда этот метод, к сожалению, не будет работать.В этом случае вам понадобится что-то вроде:

var rows = 
    df.Rows.Select(row =>
      new Person { Name = row.Value.GetAs<string>("Name"), 
                   Age = row.Value.GetAs<int>("Age"))).Observations;
...