为啥 Dictionary<TKey, TValue> 上的这个 Linq 查询不能作为数据源工作

Posted

技术标签:

【中文标题】为啥 Dictionary<TKey, TValue> 上的这个 Linq 查询不能作为数据源工作【英文标题】:Why isn't this Linq query on Dictionary<TKey, TValue> working as DataSource为什么 Dictionary<TKey, TValue> 上的这个 Linq 查询不能作为数据源工作 【发布时间】:2011-05-29 00:27:06 【问题描述】:

我在 VB 中有以下内容:

Dim sources = From source In importSources Select New With _
    .Type = source.Key, .Source = source.Value.Name

dgridSourceFiles.DataSource = sources

当我调试时,sources 显示了一个内存查询,其中有 2 条记录。然而数据网格视图不会显示记录。

那么为什么这不起作用?建议可以是 VB 或 C#...

更新

当我使用时:

Dim sources = (From source In importSources Select New With _
    .Type = source.Key, .Source = source.Value.Name).ToList()

...显示数据源。

【问题讨论】:

【参考方案1】:

您的 LINQ 查询被延迟评估并仅实现 IEnumerable&lt;T&gt; 接口(据我所知),这意味着直到枚举器在某处调用 MoveNext 时才会确定其结果(就像在 foreach 循环中发生的那样,例如)。

DataSource 属性似乎没有以这种方式枚举其内容。它完全期待IList(或其他几个接口之一——见下文)的实现,以便它可以按索引访问项目。这由控件在内部用于排序、过滤等。考虑到这一点,很可能所有设置DataSource 属性所做的就是检查对象的类型以查看它是否实现了任何受支持的接口。所以我认为DataSource 属性根本不是为了处理这种类型的对象(延迟评估的查询)而设计的。

现在,ToList 调用会使用您的查询结果填充 List&lt;T&gt;;这确实实现了IList,因此可以用作DataSource

我的理解是,DataSource 仅输入为object 的原因是它需要以下接口中的任何

IList IListSource(在这种情况下,IListSource.GetList 方法与DataMember 属性一起使用以向控件提供数据) IBindingList(将列表中的更改传播到控件以进行 UI 更新) IBindingListView(如BindingSource

这是根据MSDN documentation.

【讨论】:

我不这么认为。 DataSource 上的 MSDN 文档说它必须是 Nothing 或实现 IEnumerable 或 IListSource。 msdn.microsoft.com/en-us/library/… @jwiscarson:您发布的链接是针对System.Web.UI.WebControls.BaseDataList,而不是DataGridView(这是一个Windows 窗体控件)。 @Dan,你是对的,关于 WinForms 网格的 DataSource 对象也是对的。 OP 需要更新这篇文章,阐明 WebForms 与 WinForms。我将“数据网格视图”误解为数据网格的通用视图。 @jwiscarson:当然可以更清楚,但问题确实包括标签datagridview;所以我认为我们在这里讨论的是 WinForms。 同意,并 +1。我从来没有提交过这个问题的答案,因为这个问题太令人困惑了,而且不知道帖子中可能缺少哪些细节会导致这个问题,所以你的回答特别有见地。【参考方案2】:

您可能需要在设置源后调用 DataBind。试试:

dgridSourceFiles.DataSource = sources
dgridSourceFiles.DataBind()

【讨论】:

我在 DataGridView 上没有 DataBind() 方法。当我看到另一个解决方案时,我已经想到了这一点。 @dboarman:正式注明。我大部分时间都生活在 Web 世界中,所以我正在考虑一个 GridView 控件。 :-)

以上是关于为啥 Dictionary<TKey, TValue> 上的这个 Linq 查询不能作为数据源工作的主要内容,如果未能解决你的问题,请参考以下文章

System.Collections.Generic.Dictionary<TKey,TValue>

Dictionary<TKey, TValue> 的线程安全

我可以为 Dictionary<TKey, TValue> 条目使用集合初始化程序吗?

Dictionary<TKey, TValue> 中的散列过程是如何工作的

Lookup<TKey, TElement> 的意义何在?

ConcurrentDictionary与Dictionary