C# 交互式代理API数据表覆盖行

C# 交互式代理API数据表覆盖行,c#,datatable,interactive-brokers,C#,Datatable,Interactive Brokers,我正在使用InteractiveBrokersCAPI并试图从AccountSummary对象创建一个Datatable,但表中的行被覆盖,只显示最后一个值 我不知道发生了什么事。我认为可能是属性类型与列名匹配,因此在同一行的顶部写得太多 预期产量 这是调用ConvertToDataTable方法的方法 public void UpdateUI(IBMessage message) { switch (message.Type) {

我正在使用InteractiveBrokersCAPI并试图从AccountSummary对象创建一个Datatable,但表中的行被覆盖,只显示最后一个值

我不知道发生了什么事。我认为可能是属性类型与列名匹配,因此在同一行的顶部写得太多

预期产量

这是调用ConvertToDataTable方法的方法

public void UpdateUI(IBMessage message)
    {
        switch (message.Type)
        {
            case MessageType.AccountSummary:                    
                ConverToDataTable((AccountSummaryMessage)message);
                break;
            case MessageType.AccountSummaryEnd:
                HandleAccountSummaryEnd();
                break;
            case MessageType.AccountValue:
                HandleAccountValue((AccountValueMessage)message);
                break;
            case MessageType.PortfolioValue:
                HandlePortfolioValue((UpdatePortfolioMessage)message);
                break;
            case MessageType.AccountDownloadEnd:
                break;
            case MessageType.Position:
                HandlePosition((PositionMessage)message);
                break;
            case MessageType.PositionEnd:
                break;
        }
    }
这就是我试图从中构建数据表的对象

public class AccountSummaryMessage : IBMessage
{
    private int requestId;
    private string account;
    private string tag;
    private string value;
    private string currency;

    public int RequestId
    {
        get { return requestId; }
        set { requestId = value; }
    }

    public string Account
    {
        get { return account; }
        set { account = value; }
    }

    public string Tag
    {
        get { return tag; }
        set { tag = value; }
    }

    public string Value
    {
        get { return this.value; }
        set { this.value = value; }
    }

    public string Currency
    {
        get { return currency; }
        set { currency = value; }
    }

    public AccountSummaryMessage(int requestId, string account, string tag, string value, string currency)
    {
        Type = MessageType.AccountSummary;
        RequestId = requestId;
        Account = account;
        Tag = tag;
        Value = value;
        Currency = currency;
    }
}

在添加行之前,应该首先循环并将列添加到表中。如果您只是试图在ConvertODatable函数中创建一个包含单行的表,则需要将其更改为类似以下内容:

public static DataTable ConverToDataTable(object obj)
{
    DataTable dt = new DataTable();

    var dataType = obj.GetType();

    dataType.GetProperties().ToList().ForEach(f =>
    {
        try
        {
            dt.Columns.Add(f.Name, f.PropertyType);
        }
        catch
        {

        }
    });

    DataRow newRow = dt.NewRow();
    foreach (var prop in dataType.GetProperties())
    {
        newRow[prop.Name] = prop.GetValue(obj);
    }
    dt.Rows.Add(newRow);

    return dt;
}
编辑:如我在下面的评论中所解释的,要添加多行,您有几个选项。以下是两种可能的方法:

在类中使用私有表变量在需要时继续追加行:

使用可枚举类型一次添加所有行:


了解可枚举类型可能会有所帮助。这是一个很好的开始。

我使用了Kevin的第一个编辑,它工作得非常完美。

您从哪里调用ConvertODatable?您是在列表上循环还是在AccountSummaryMessage对象的多个实例上以任何方式调用该函数?嗨,Kevin/jstreet,感谢您花时间回答。我添加了调用ConvertToDataable方法的方法。我仍然无法理解将在何处追加多行。每次调用ConvertToDataTable时,您都在创建一个包含一行的新数据表。嗨,Kevin,谢谢您的帮助。我添加了一张我正在努力实现的图片。我正在尝试显示多行。当我使用datagridview时,我可以获得预期的输出,但当尝试使用datatable时,我无法获得正确的输出。是否在函数中指定ConvertDataTable的返回值?或者传递obj参数的可枚举类型?我看不到任何其他使用该函数添加多行的方法。不,这两种方法都没有。我以前从未使用过可枚举类型。我认为您有两种选择:1。您可以将DataTable保留为私有/公共变量,并将函数更改为附加返回的DataTable,或将函数更改为非静态void并修改DataTable变量。2.您可以向函数传递一个可枚举项,并一次追加所有行。我会更新我的答案给你们看。非常感谢Kevin,这很有效,也阅读了IEnumerables,很有趣地看到了a for each在幕后是如何工作的。
public static DataTable ConverToDataTable(object obj)
{
    DataTable dt = new DataTable();

    var dataType = obj.GetType();

    dataType.GetProperties().ToList().ForEach(f =>
    {
        try
        {
            dt.Columns.Add(f.Name, f.PropertyType);
        }
        catch
        {

        }
    });

    DataRow newRow = dt.NewRow();
    foreach (var prop in dataType.GetProperties())
    {
        newRow[prop.Name] = prop.GetValue(obj);
    }
    dt.Rows.Add(newRow);

    return dt;
}
private DataDate table = null;

public void ConverToDataTable(object obj)
{
    var dataType = obj.GetType();

    if (table == null)
    {
        table = new DataTable();

        dataType.GetProperties().ToList().ForEach(f =>
        {
                table.Columns.Add(f.Name, f.PropertyType);
        });
    }

    DataRow newRow = table.NewRow();
    foreach (var prop in dataType.GetProperties())
    {
        newRow[prop.Name] = prop.GetValue(obj);
    }
    table.Rows.Add(newRow);
}
public static DataTable ConverToDataTable(IEnumerable<object> obj)
{
    DataTable dt = new DataTable();

    var dataType = obj.First().GetType();

    dataType.GetProperties().ToList().ForEach(f =>
    {
        try
        {
            dt.Columns.Add(f.Name, f.PropertyType);
        }
        catch
        {

        }
    });

    foreach (var item in obj)
    {
        DataRow newRow = dt.NewRow();
        foreach (var prop in dataType.GetProperties())
        {
            newRow[prop.Name] = prop.GetValue(item);
        }
        dt.Rows.Add(newRow);
    }

    return dt;
}