我是Delphi开发人员和C#开发人员。 C#具有DataTable类,支持对Rows的随机访问。是否存在类似DataTable(C#)的第三方TDataSet(Delphi)组件?
答案 0 :(得分:7)
Delphi中有TClientDataSet
类,其功能类似于.NET中的DataSet
。
答案 1 :(得分:2)
您可以将TADODataSet
用于断开连接的内存数据集as suggested by Ian。与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;
然后,您可以使用TDataSource
将其绑定到TADODataSet
,并根据需要使用数据感知控件链接到TDataSource
。
答案 2 :(得分:1)
Data Storage Engine。通常,它是ADO.NET v 1,但对于本机代码。它可以与TADMemTable一起使用。
PS:AnyDAC是商业产品。
答案 3 :(得分:1)
kbmMemTable CodeGear Edition,您可以在https://portal.components4developers.com注册后免费下载为kbmMW CodeGear Edition的一部分(忽略证书错误,如果发生任何错误......网站 有效)
kbmMemTable CodeGear Edition包含Delphi内存表最丰富的功能..免费。 它甚至包含:
如果您需要源kbmMemTable标准版可用,如果您需要在Delphi内存数据集中找到的最佳性能,您可以将kbmMemTable专业版作为kbmMW专业版和kbmMW企业版的捆绑部分。
最好的问候 金马森 www.components4developers.com答案 4 :(得分:1)
JVCL具有TjvMemoryData,它支持对行和字段的随机访问。它比Delphi自己的TClientDataSet更灵活。
答案 5 :(得分:1)
Cary Jensen有一个很好的系列,比较ClientDataSets和DataTables:In-Memory DataSets: ClientDataSet and .NET DataTable Compared: Part 1 Overview
答案 6 :(得分:1)
SQLMemTable是一个功能齐全的内存数据库系统;它 包括数据库,表,查询和批处理移动组件以及 有用的实用程序(带源代码),演示和全面的帮助。 SQLMemTable不需要BDE或任何外部驱动程序,并且很小 足迹。
另一个免费(开源)组件是TxQuery(MPL)
TxQuery组件是可以使用的TDataSet后代组件 使用SQL查询一个或多个TDataSet后代组件 语句
答案 7 :(得分:1)
目标是拥有纯粹的记忆TDataSet
。 TClientDataSet
(除了bugs)之外的问题是,您将依赖客户在其计算机上不具备的DLL。 (意思是你有一个dll加密狗船。)
幸运的是,Microsoft已经创建了一个客户端,内存中,本机等效于DataTable
:ADO Recordset
。
你可以制作你的ADO Recordset
,给它字段,然后将它包装在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 | | | |
答案 8 :(得分:0)
您可能对 Inovativa (http://www.inovativa.com.br/public)中的 TECDataset (EverClassy Dataset)感兴趣,这是一个可以填充对象的内存数据集任何阶级。