C# Delphi中的DataTable(类似数据集)组件

C# Delphi中的DataTable(类似数据集)组件,c#,delphi,tdataset,C#,Delphi,Tdataset,我是Delphi开发人员和C#开发人员。C#具有支持对行进行随机访问的DataTable类。是否有类似DataTable(C#)的第三方TDataSet(Delphi)组件?Delphi中有类,其功能与.NET中的类似。在任何DAC中。一般来说,它是v1,但是对于本机代码。它可以与TADMemTable一起使用 PS:AnyDAC是一种商业产品。kbmMemTable CodeGear版本,您可以在注册后作为kbmMW CodeGear版本的一部分免费下载(如果出现任何证书错误,请忽略)。该网站

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

Delphi中有类,其功能与.NET中的类似。

在任何DAC中。一般来说,它是v1,但是对于本机代码。它可以与TADMemTable一起使用


PS:AnyDAC是一种商业产品。

kbmMemTable CodeGear版本,您可以在注册后作为kbmMW CodeGear版本的一部分免费下载(如果出现任何证书错误,请忽略)。该网站有效)


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

  • SQL支持高级高性能索引筛选书签
  • 数据集与其他数据集源和目标的交换
  • 主控/明细多个游标(以及单独的筛选器和索引)以
  • 物理上相同的数据非常高的性能版本控制和
  • 跟踪数据更改,包括解决这些更改的能力
  • 通过Deltahandles到其他地方的变更
  • 此外,该产品还有数百项功能和优点
如果您需要源代码kbmMemTable Standard Edition可用,并且需要在Delphi内存数据集中找到最佳性能,则可以将kbmMemTable Professional Edition作为kbmMW Professional Edition和kbmMW Enterprise Edition的捆绑部分获得

致意 马德森
www.components4developers.com

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

Cary Jensen提供了一个优秀的系列,比较ClientDataSet和DataTables:

一个免费(供个人使用)内存数据库表可从

SQLMemTable是一个功能齐全的内存数据库系统;信息技术 包括数据库、表、查询和批处理移动组件以及 实用工具(含源代码)、演示和全面帮助。 SQLMemTable不需要BDE或任何外部驱动程序,并且具有较小的 足迹

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

TxQuery组件是可以使用的TDataSet子组件 使用SQL查询一个或多个TDataSet子体组件 声明


您可能对来自Inovativa的TECDataset(EverClassy数据集)感兴趣,这是一个内存中的数据集,可以用任何类的对象填充。

目标是拥有一个纯内存
TDataSet
TClientDataSet
(除了)的问题是,您将依赖于客户计算机上没有的DLL。(意思是你有一个船的dll加密狗)

幸运的是,微软已经在内存中创建了一个与
数据表
:ADO
记录集
相当的客户端

您可以使ADO
记录集
,为其指定字段,然后将其包装在一个
TADODataSet
中,使其从规范的Delphi
TDataSet
(或者您可以直接使用ADO记录集对象)

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

//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);
您还必须
打开
记录集以具体化字段:

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 |          |          |              |
可以用于断开连接的内存中数据集。与
TClientDataSet
IMO相比,它非常强大

但是不需要所有低级的
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;

然后,您可以使用将其绑定到
tODataSet
,并在需要时使用链接到
TDataSource

的数据感知控件。不幸的是
TClientDataSet
依赖于客户端机器上尚未存在的外部dll。我给您一个+1来建议ADO并提及
TClientDataSet
Bug,但您真的不需要所有这些低级ADO的东西。看看我的答案…@kobik谢谢你。这正是我希望发生的事情——有人接受我的答案,然后带着它跑。
ds.First;
ds.Edit;
ds.FieldByName('InvoiceNumber').AsInteger := 1786;