4

我是 Delphi 开发人员和 C# 开发人员。C# 具有支持随机访问行的 DataTable 类。是否有类似于 DataTable (C#) 的第三方 TDataSet (Delphi) 组件?

4

9 回答 9

7

Delphi 中有TClientDataSet类,其功能类似于DataSet.NET 中的类。

于 2012-04-25T05:45:44.800 回答
2

您可以使用Ian 建议TADODataSet的断开连接的内存数据集。与IMO相比,它非常强大。TClientDataSet

ADO但是不需要所有低级的东西。它很简单:

var 
   ds: TADODataSet;

ds := TADODataSet.Create(nil);

//add our fields
ds.FieldDefs.Add('InvoiceNumber', ftInteger);
ds.FieldDefs.Add('CustomerName',  ftWideString, 200);
ds.FieldDefs.Add('CreatedDate',   ftDateTime);
ds.FieldDefs.Add('Comments',      ftWideMemo);
ds.FieldDefs.Add('Quantity',      ftFloat);
ds.FieldDefs.Add('InvoiceTotal',  ftCurrency);
ds.CreateDataSet;

//Add a row of values - the easy way
ds.Append;
ds.FieldByName('InvoiceNumber').AsInteger := 1783;
ds.FieldByName('CustomerName').AsString   := 'Hubert Farnsworth';
ds.FieldByName('CreatedDate').AsDateTime  := Now;
ds.FieldByName('Comments').AsString       := 'The quick brown fox jumped over the lazy dog';
ds.FieldByName('Quantity').AsFloat        := 19809.32; //imperial gallons
ds.FieldByName('InvoiceTotal').AsCurrency := 99.95; //GBP
ds.Post;

//Add another row of values - with an array of values all at once
ds.AppendRecord([1784, 'Steven Gates', Now, '//no comment', 1292, 19.25]);

您还可以编辑现有数据:

ds.First;
ds.Edit;
ds.FieldByName('InvoiceNumber').AsInteger := 1786;

然后,您可以使用TDataSource将其绑定到TADODataSet并在需要时使用数据感知控件链接到TDataSource.

于 2017-07-26T08:48:22.737 回答
1

AnyDAC 中的数据存储引擎。通常,它是ADO.NET v 1,但用于本机代码。它可以与 TADMemTable 一起使用。

PS:AnyDAC 是商业产品。

于 2012-04-25T05:53:24.693 回答
1

kbmMemTable CodeGear 版,您可以在https://portal.components4developers.com注册后作为 kbmmW CodeGear 版的一部分免费下载(如果出现任何错误,请忽略证书。该站点有效)。

kbmMemTable CodeGear Edition 包含功能最丰富的 Delphi 内存表.. 免费。它甚至包含:

  • SQL 支持高级高性能索引过滤书签
  • 与其他数据集源和目标的数据集交换
  • master/detail 多个游标(以及单独的过滤器和索引)
  • 物理上相同的数据非常高性能的版本控制和
  • 跟踪数据更改,包括解决这些问题的能力
  • 通过 deltahandlers 更改到其他地方
  • 加上产品中的数百个功能和好东西

如果您需要源 kbmMemTable 标准版可用,并且如果您需要可以在 Delphi 内存数据集中找到的最佳性能,您可以将 kbmMemTable 专业版作为 kbmMW 专业版和 kbmMW 企业版的捆绑部分。

最好的问候金马德森 www.components4developers.com

于 2012-04-25T18:04:38.460 回答
1

JVCL 有支持随机访问行和字段的 TjvMemoryData。它比 Delphi 自己的 TClientDataSet 灵活一点。

于 2012-04-25T20:40:13.477 回答
1

Cary Jensen 有一个比较 ClientDataSets 和 DataTables 的优秀系列:内存中数据集:ClientDataSet 和 .NET DataTable 比较:第 1 部分概述

于 2012-04-26T12:40:41.023 回答
1

AidAim提供免费(供个人使用)内存数据库表

SQLMemTable 是一个功能齐全的内存数据库系统;它包括数据库、表、查询和批量移动组件以及有用的实用程序(带有源代码)、演示和全面的帮助。SQLMemTable 不需要 BDE 或任何外部驱动程序,并且占用空间小。

另一个免费(开源)组件是TxQuery (MPL)

TxQuery 组件是一个 TDataSet 后代组件,可用于使用 SQL 语句查询一个或多个 TDataSet 后代组件

于 2012-04-26T14:27:34.813 回答
1

目标是拥有一个纯粹的内存TDataSetTClientDataSet(除了错误)的问题是,您将依赖客户在他们的计算机上没有的 DLL。(意味着你有一个 dll 加密狗)。

幸运的是,微软已经创建了一个客户端的、内存中的、本机等效的 a DataTable:ADO Recordset

您可以制作您的 ADO Recordset,为其提供字段,然后将其包装在 a 中TADODataSet,以便它从规范的 Delphi 中继承TDataSet(或者您可以直接使用 ADO Recordset 对象)。

var
    rs: Recordset;

//Use ADO Recordset to hold our in-memory table
rs := CoRecordset.Create;
rs.CursorLocation := adUseClient; //default is adUseServer

现在您有了记录集,您可以定义字段:

//add our fields
rs.Fields.Append('InvoiceNumber', adInteger,      0,   adFldUpdatable, EmptyParam);
rs.Fields.Append('CustomerName',  adVarWChar,     200, adFldUpdatable, EmptyParam);
rs.Fields.Append('CreatedDate',   adDBTimeStamp,  0,   adFldUpdatable, EmptyParam);
rs.Fields.Append('Comments',      adLongVarWChar, -1,  adFldUpdatable, EmptyParam);
rs.Fields.Append('Quantity',      adDouble,       0,   adFldUpdatable, EmptyParam);
rs.Fields.Append('InvoiceTotal',  adCurrency,     0,   adFldUpdatable, EmptyParam);

您还必须对Open记录集实现字段:

var
   o: OleVariant;

//It's impossible in Delphi to omit parameters. So we do it the late-binding IDispatch way
//  rs.Open(EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
o := (rs as IDispatch);
o.Open;

您有空的内存表。现在您可以添加数据行:

//Add a row of values - the easy way
rs.AddNew(EmptyParam, EmptyParam); //moves cursor to newly added row
rs.Fields['InvoiceNumber'].Value := 1783;
rs.Fields['CustomerName'].Value  := 'Hubert Farnsworth';
rs.Fields['CreatedDate'].Value   := Now;
rs.Fields['Comments'].Value      := 'The quick brown fox jumped over the lazy dog';
rs.Fields['Quantity'].Value      := 19809.32; //imperial gallons
rs.Fields['InvoiceTotal'].Value  := 99.95; //GBP

//Add another row of values - you can add by single value
rs.AddNew('InvoiceNumber', 1784);

//Add another row of values - you can add by field names
rs.AddNew(VarArrayOf(['InvoiceNumber', 'InvoiceTotal']), VarArrayOf([1784, 22.37]));

//Add another row of values - you can add by ordinal index
rs.AddNew(VarArrayOf([0, 2]), VarArrayOf([1785, Now]));

//Move to the start of the Recordset, so it will be ready for the person using it.
if (not rs.BOF) or (not rs.EOF) then //You can't MoveFirst on a Recordset if the Recordset is empty. (It's throws an error instead of not throwing an error)
rs.MoveFirst;

最后,我们想要一个熟悉的TDataSet包装器:

var
   dataset: TDataSet;      

//Wrap the recordset is a TDataSet descendant 
//that knows how to talk to an ADO recordset: the TADODataSet.
dataset := TADODataSet.Create(nil);
dataset.Recordset := rs;

所以我可以测试它:

var 
   ds: TDataSet;
begin
   ds := CreateMemoryDataSet();
   ShowMessage(DataSetToMarkdown(ds));

我得到了预期的内存数据:

| InvoiceNumber | CustomerName      | CreatedDate          | Comments | Quantity | InvoiceTotal |
|---------------|-------------------|----------------------|----------|----------|--------------|
| 1783          | Hubert Farnsworth | 7/25/2017 3:32:21 PM | The quick brown fox jumped over the lazy dog | 19809.32 | 99.95 |
| 1784          |                   |                      |          |          |              |
| 1784          |                   |                      |          |          | 22.37        |
| 1785          |                   | 7/25/2017 3:32:22 PM |          |          |              |

您还可以修改内存中的值:

ds := CreateMemoryDataSet();    
ds.First;
ds.Edit;
ds.FieldByName('InvoiceNumber').AsInteger := 1786;
ShowMessage(DataSetToMarkdown(ds));

| InvoiceNumber | CustomerName      | CreatedDate          | Comments | Quantity | InvoiceTotal |
|---------------|-------------------|----------------------|----------|----------|--------------|
| 1786          | Hubert Farnsworth | 7/25/2017 3:32:21 PM | The quick brown fox jumped over the lazy dog | 19809.32 | 99.95 |
| 1784          |                   |                      |          |          |              |
| 1784          |                   |                      |          |          | 22.37        |
| 1785          |                   | 7/25/2017 3:32:22 PM |          |          |              |
于 2017-07-25T20:48:49.687 回答
0

您可能对来自Inovativa ( http://www.inovativa.com.br/public ) 的TECDataset (EverClassy Dataset)感兴趣,它是一个内存数据集,可以填充任何类的对象。

于 2013-06-26T10:56:16.187 回答