【问题标题】:Binding a GridView to a Dynamic or ExpandoObject object将 GridView 绑定到 Dynamic 或 ExpandoObject 对象
【发布时间】:2011-07-31 05:44:33
【问题描述】:

我正在使用 Rob Conery 的 Massive ORM,但我无法将生成的 ExpandoObject 绑定到 GridView

我确实找到了另一个 Stackoverflow 问题,该问题建议使用名为 impromptu 的框架,但我不确定这是否适用。如果您知道,请提供代码示例以将 ExpandoObject 实际转换为 GridView 控件可以绑定到的内容。

最坏的情况,是否有人为 Massive 实现了一个额外的方法(可以共享)来将生成的 ExpandoObject 转换为 POCO?

非常感谢任何帮助。谢谢。

【问题讨论】:

标签: .net gridview dynamic orm expandoobject


【解决方案1】:

由于无法绑定到 ExpandoObject,因此可以将数据转换为 DataTable。此扩展方法将为您做到这一点。我可能会将其提交给 Massive。

/// <summary>
/// Extension method to convert dynamic data to a DataTable. Useful for databinding.
/// </summary>
/// <param name="items"></param>
/// <returns>A DataTable with the copied dynamic data.</returns>
public static DataTable ToDataTable(this IEnumerable<dynamic> items) {
    var data = items.ToArray();
    if (data.Count() == 0) return null;

    var dt = new DataTable();
    foreach(var key in ((IDictionary<string, object>)data[0]).Keys) {
        dt.Columns.Add(key);
    }
    foreach (var d in data) {
        dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
    }
    return dt;
}

【讨论】:

  • 那么你怎么能得到双向数据绑定
【解决方案2】:

如果我们在谈论 GridView(意思不是 WPF),那么impromptu 可以在给定接口的情况下将 expando 代理到 poco。假设我们有一个 expando 列表,您可以将它们转换为 poco:

IEnumerable<IMyInterface> listOfPocos
       = Impropmtu.AllActLike<IMyInterface>(listOfExpandos, typeof(INotifyPropertyChanged));

【讨论】:

    【解决方案3】:

    我修改了 Brian 接受的答案,使其更加简洁和 LINQ-y:

    public static DataTable ToDataTable(this IEnumerable<dynamic> items)
    {
        var list = items.Cast<IDictionary<string, object>>().ToList();
        if(!list.Any()) return null;
    
        var table = new DataTable();
        list.First().Keys.Each(x => table.Columns.Add(x));
        list.Each(x => x.Values.Each(y => table.Rows.Add(y)));
    
        return table;
    }
    

    (假设您已经定义了一个 IEnumerable.Each 扩展,我工作过的每个代码库都有)。

    【讨论】:

    • 当“List”有一个 ForEach 方法做同样的事情时,为什么要使用 Each Extension
    • 因为否则您需要将键和值(IEnumerable)转换为 List
    • 当你没有返回结果时,我会说在IEnumerable&lt;T&gt;上使用foreach
    【解决方案4】:

    我在研究同一主题后来到这个主题,我没有找到解决方案,但我自己构建了一个,因为我非常需要这个。所以这是我的解决方案,而不是真正有效的 POCO。

    // Fill "list" with your dynamic objects.
    
    // cast a dynamic object to dictionary so we get the properties from it.
    var props = list[0] as IDictionary<string, object>;
    
    // create a datatable 
    var table = new System.Data.DataTable();
        foreach (var c in props.Keys)
            table.Columns.Add(new DataColumn(c));
    
    foreach (var o in list)
    {
        var row = table.NewRow();
        var op =  o as IDictionary<string, object>;
        foreach (var p in op.Keys)
        {
            row[p] = op[p];
        }
        table.Rows.Add(row);
    }
    

    只需将此表绑定到您的网格!

    我测试了它,它对我有用。

    【讨论】:

      【解决方案5】:

      好的,显然到目前为止,您还不能将 GridView 控件绑定到 ExpandoObject 实例。我不得不使用反射将 ExpandoObject 转换为 POCO 类。

      【讨论】:

      • 您是如何做到这一点的?你能发布样品吗?
      【解决方案6】:

      改编自本的回答

       public static DataTable ToDataTable(this IEnumerable<dynamic> items)
          {
              if (!items.Any()) return null;
      
              var table = new DataTable();
              bool isFirst = true;
      
              items.Cast<IDictionary<string, object>>().ToList().ForEach(x =>
              {
                  if (isFirst) 
                    {
                      x.Keys.Select(y => table.Columns.Add(y)).ToList();
                      isFirst = false;
                    }
                  table.Rows.Add(x.Values.ToArray());
              });
      
              return table;
          }
      

      【讨论】:

        【解决方案7】:
        /// <summary>
        /// Extension method to convert dynamic data to a DataTable. Useful for databinding.
        /// </summary>
        /// <param name="items"></param>
        /// <returns>A DataTable with the copied dynamic data.</returns>
        public static DataTable ToDataTable(this IEnumerable<dynamic> items)
        {
            var data = items.ToArray();
            if (data.Count() == 0) return null;
        
            var dt = new DataTable();
            foreach (var pair in ((IDictionary<string, object>)data[0]))
            {
                dt.Columns.Add(pair.Key, pair.Value.GetType());
            }
        
        
            foreach (var d in data)
            {
                dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
            }
            return dt;
        }
        

        【讨论】:

        • 你的答案已被收录here,请删除。
        猜你喜欢
        • 2011-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-27
        • 1970-01-01
        • 2013-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多