简体   繁体   English

.NET 需要一个真正的数据感知和数据驱动的网格,它使用 GUID 作为行句柄

[英]need a truly data-aware and data-driven grid for .NET that uses GUIDs as row-handles

I am looking for a data-aware grid for .NET that has been optimized for repeated changes of the underlying dataset.我正在为 .NET 寻找数据感知网格,该网格已针对基础数据集的重复更改进行了优化。 I will give an example to show what I mean by optimized in that context, since almost all grids let you change the datasource.我将举一个例子来说明我在这种情况下优化的意思,因为几乎所有网格都允许您更改数据源。 But going way back to the OCX days, changing the datasource has caused problems for data-aware grids.但是回到 OCX 时代,改变数据源给数据感知网格带来了问题。

This data-aware data-driven grid must not use integer row handles.此数据感知数据驱动网格不得使用 integer 行句柄。 It must use GUID row handles .它必须使用 GUID 行句柄 That is the single most important requirement of this grid.这是这个网格最重要的要求。

Each row of the underlying dataset is assigned a GUID rowHandle, not an integer, and no matter how the datarows happen to be sorted or grouped, a datarow's GUID rowHandle stays with it, and a datarow can be instantly retrieved by its rowHandle.底层数据集的每一行都分配有一个 GUID rowHandle,而不是 integer,并且无论数据行如何排序或分组,数据行的 GUID rowHandle 都会保留,并且可以通过其 rowHandle 立即检索数据行。

The grid's FocusedRowChanged event is fired when the GUID of the currently focused row is not the same as the GUID of the row that most recently had the focus.当当前获得焦点的行的 GUID 与最近获得焦点的行的 GUID 不同时,将触发网格的FocusedRowChanged事件。 [EDIT: In a grid that uses integer row handles, it's often the case that when the datasource is changed the FocusedRowChanged event will not fire because the focused-row-position has not changed; [编辑:在使用 integer 行句柄的网格中,通常在更改数据源时不会触发 FocusedRowChanged 事件,因为焦点行位置没有改变; eg the focus was on the first row before the datasource change and the focus is on the first row after the datasource change;例如,焦点在数据源更改前的第一行,焦点在数据源更改后的第一行; the integer row handle is the same even though the underlying row data is completely different.]即使基础行数据完全不同,integer 行句柄也是相同的。]

I want the grid to be truly data-aware and data-driven in its behavior;我希望网格的行为是真正的数据感知和数据驱动; eg例如

Grid.GroupByColumnNames = {"customername","city"};
Grid.Groups["customername"].ExpandedValues = {"Acme Widgets", "Foo Industrial"};
Grid.Groups["city"].ExpandedValues = {"New York","Miami"};

Now, if I cleared the dataset the underlies the grid above and substituted another dataset for its datasource, which also had customername and city columns, and contained values Acme Widgets and Foo Industrial in that column, the grid would group the new dataset by the customername and city columns, and expand those companies (if a PreserveGroupingsWhenDataSetChanges flag is set to True).现在,如果我清除上面网格的基础数据集并用另一个数据集替换其数据源,该数据源也有客户名称和城市列,并在该列中包含值 Acme Widgets 和 Foo Industrial,网格将按客户名称对新数据集进行分组和城市列,并展开这些公司(如果 PreserveGroupingsWhenDataSetChanges 标志设置为 True)。

There is something fundamentally wrong with this question which is why after several months nobody has provided a good answer.这个问题有一些根本性的错误,这就是为什么几个月后没有人提供一个好的答案。 Even if your data's primary key is a GUID it does not justify having the row handles for a control being GUIDs.即使您的数据的主键是 GUID,它也不能证明控件的行句柄是 GUID。 In fact this is a pretty bad idea.事实上,这是一个非常糟糕的主意。 GUIDs are 128 bits (16 bytes) while ints are generally 32-bits - but more important than the number of bits (say it was 64 in certain environments) is that int operations are atomic meaning you can read/write an int without locking between threads and is higher performance. GUID 是 128 位(16 字节),而 int 通常是 32 位 - 但比位数更重要(比如在某些环境中是 64 位)是 int 操作是原子的,这意味着您可以读取/写入 int 而无需在两者之间锁定线程和更高的性能。 So GUIDs have higher memory footprint and higher cost for processing (reading/writing would be multiple operations each).因此 GUID 具有更高的 memory 占用空间和更高的处理成本(每个读/写将是多个操作)。

So really any control should be using fast/lean code visually and just referencing the datasource when necessary to fetch the primary key or other bits of data.因此,实际上任何控件都应该在视觉上使用快速/精简代码,并且在需要获取主键或其他数据位时仅引用数据源。

My Experience With and Thoughts About Grids我对网格的体验和思考

I happen to like DevExpress controls for winforms and also use their data layer component XPO.我碰巧喜欢用于 winforms 的 DevExpress 控件,并且还使用它们的数据层组件 XPO。 However there are multiple component vendors with similar controls and data layers (which generally all share the feature of separating rowhandles from data primary keys).然而,有多个组件供应商具有相似的控件和数据层(它们通常都共享将行句柄与数据主键分离的特性)。

In DevExpress they have an excellent grid which is Data Aware and provides a multitude of events for you to tie into for all sorts of possible changes.在 DevExpress 中,他们有一个出色的网格,它是数据感知的,并为您提供了大量事件,以供您参与各种可能的更改。

There XPO datalayer can use anything for a primary key including either an int or Guid. XPO 数据层可以使用任何东西作为主键,包括 int 或 Guid。 I use Guids along with a lot of other developers due to the ability to insert primary keys from remote machines or offline data (I can't say I've ever been responsible for a database with more than 2 billion records in a table, but maybe you are).由于能够从远程机器或离线数据中插入主键,我和许多其他开发人员一起使用 Guids(我不能说我曾经负责过一个表中有超过 20 亿条记录的数据库,但是也许你是)。

While the primary key for my data may be a GUID the row handles are still ints.虽然我的数据的主键可能是 GUID,但行句柄仍然是整数。 This will be significantly faster behind the scenes than an Guid would be.这在幕后将比 Guid 快得多。 However, they still provide a bunch of methods for going back and forth between the visual index, row handle, and data source index as well as a few methods for fetching the underlying data source row by the row handle.但是,它们仍然提供了一堆在可视索引、行句柄和数据源索引之间来回切换的方法,以及一些通过行句柄获取底层数据源行的方法。 This is useful inside many of the control's events which provide row handles (not data primary keys) where you'll simply grab the data source record by the rowhandle with one line of code.这在提供行句柄(不是数据主键)的许多控件事件中很有用,您只需使用一行代码通过行句柄获取数据源记录。

Also, generally speaking, if you access a collection using a string based indexer as in your pseudo code above, components simply do an List.IndexOf() kind of call behind the scenes which is then passed on to the indexer as an int index.此外,一般来说,如果您使用基于字符串的索引器访问集合,如上面的伪代码中所示,组件只需在后台执行List.IndexOf()类型的调用,然后将其作为 int 索引传递给索引器。 So you are really still working with int based indexes behind the scenes.因此,您实际上仍在幕后使用基于 int 的索引。 Even if some component company used GUIDs for rowhandles, they'd be putting those GUIDs into a hashset or dictionary behind the scenes to lookup the int index to actually use.即使某些组件公司将 GUID 用于行句柄,他们也会将这些 GUID 放入幕后的哈希集或字典中,以查找要实际使用的 int 索引。 So it'd all just be layers on top of ints anyway, so they just leave it abstract and let you implement this kind of stuff in your code if you need it (as opposed to building it into a component library).因此,无论如何它都只是 int 之上的层,所以它们只是将其抽象化,并让您在需要时在代码中实现这种东西(而不是将其构建到组件库中)。

Recommendation推荐

The bottom line is that I think you can accomplish everything you described above with the DevExpress Grid but will have to let go of the GUID rowhandles and change your strategy a little.最重要的是,我认为您可以使用 DevExpress Grid 完成上述所有操作,但必须让 GUID 行句柄的 go 处理并稍微改变您的策略。 You may need to build your own GUID to rowhandle index as a hashset or dictionary if your application requires this kind of reverse lookup.如果您的应用程序需要这种反向查找,您可能需要构建自己的 GUID 以将行索引作为哈希集或字典。 This saves you from the performance issues if all row handles were always GUIDs but still gives you both forwards and backwards translation between GUIDs and rowhandles.如果所有行句柄始终是 GUID,但仍为您提供 GUID 和行句柄之间的正向和反向转换,这可以避免性能问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM