将 Deedle Dataframe 转换为自定义的 C# 列表 Class

Convert a Deedle Dataframe into a C# List of Custom Class

我从外部 API 接收数据作为 Deedle 数据帧。我需要获取这些数据并将其转换为自定义列表 class 以通过 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; }
}

谢谢, 尼克

有很多方法可以从 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;

@Tomas Petricek 所说的是一个很好的例子,但是有很多不同的 classes,这可能会成为一个问题。

所以我在这里举了一个例子,如何将它动态转换为特定的class,并使用属性在属性和列的索引之间进行映射。

// 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