2010-07-08 111 views
1

可以使用什么数据提供程序来从C#更新.dbf文件?从C#处理.dbf的最佳方式

我尝试了几个不同的.dbf提供程序来创建一个DataSource,但我收到这样的消息: “错误消息:错误HYC00 Microsoft ODBC dBase驱动程序可选功能未实现。

或者当我使用更新函数生成数据集和数据适配器时,我得到:“当使用修改的行传递DataRow集合时,Update需要有效的UpdateCommand。”

如果有人知道一些方法来处理来自C#的.dbf大量更新请帮助。当我尝试逐行更新行时,速度太慢,因为提供程序在搜索大型.dbf文件时会损失太多时间。也许有办法自动建立一个索引,并且数据源知道使用它?

另一种方法是将所有内容加载到类似数据集的内容中,并在完成所有更改后进行更新,但更新部分目前无法使用。

请帮忙!

回答

0

如果你坚持非常基本的SQL操作,那么vanilla OleDbConnection可以很好地处理DBF。

在这里,我工作,我们建立&维护应用程序,使用专门OleDb类与DBF交互。但是,我们不使用适配器或数据源 - 所有事情都是通过OleDbCommands,OleDbDataReaders等“直接”完成的。

也许DataAdapters依赖于与基本或传统数据源(如xBase)交互时可能不存在的功能。你有没有尝试过使用OleDbCommand的UPDATE

+0

是的,但更新太慢。我有〜1GB的基地,我必须清除每行中包含它的一些字符。如果我一行一行地做,它会花费太多,因为数据库没有索引。我必须做一些丑陋的事情,比如将所有内容全部移到内存中,删除所有记录并用更改的记录进行替换。我尝试更新替换命令,但似乎微软JET不支持它。也许有些其他供应商呢?现在我成功更新从Access中取代,但我不确定访问使用什么? – watbywbarif 2010-07-08 21:54:41

0

通常,FoxPro驱动程序与.DBF文件一起使用。文件格式非常相似,这对于阅读很有效。写作有点棘手。不幸的是,由于DBASE是一种如此古老的技术,因此.NET不能很好地处理它,所以你几乎坚持使用缓慢的选项。相信,我,我感到你的痛苦,因为我必须经常为这些POS系统配合我们的工作。

http://www.aspcode.net/Reading-DBF-files-in-C.aspx

.NET Connection to dBase .dbf file

How to read/write dBase III files using C#/.NET ODBC or OLE?

最后,我最喜欢的源连接字符串:

http://www.carlprothman.net/Default.aspx?tabid=81

+0

我通过以下链接在您推荐的网页上找到了此链接: http://www.c-sharpcorner.com/uploadfile/rfederico/xbaseenginerfv12022005011623am/xbaseenginerfv.aspx 它看起来很有前途,生病让它在前些天尝试。 – watbywbarif 2010-07-08 22:08:39

1

从你一下〜1GB数据库COMENT,我也有工作VFP数据库(.dbf)文件格式和SQL-Updates w ork没有问题通过OleDbCommand创建/执行,并且可以使用VFP OleDbProvider运行的任何本机命令。为了试图删除一些字符,我通常使用函数CHRTRAN()(也就是说,如果你使用Visual Foxpro Ole DB提供程序),在那里你可以从字面上去掉很多字符(比如无效)。 ..

Update YourTable 
    set SomeField = chrtran(SomeField, "[email protected]#$%^*(", "") 

将通过所有的记录,并从外地(第一个参数)中去掉任何,个性(2ST参数)的任何实例,并改变它的第三个参数找到相应的字符...在这种情况下,没有值,只是一个空字符串,所以字符将被删除。本身速度非常快,您不必继续扫描所有正在下载,测试,然后推回的记录。

再说一次,并非肯定您正在使用的本机.DBF文件系统,但VFP对于此类操作非常快速。

1

您可以使用LINQ to VFP来读取和写入DBF文件。我用它来编辑一些dBase III文件,像魅力一样。

定义你的表格到DBF定义这样的匹配:

public partial class MyTable 
{ 
    public System.Int32 ID { get; set; } 
    public System.Decimal Field1 { get; set; } 
    public System.String Field2 { get; set; } 
    public System.String Field3 { get; set; } 
} 

您定义的背景是这样的:

public partial class Context : DbEntityContextBase 
{ 
    public Context(string connectionString) 
     : this(connectionString, typeof(ContextAttributes).FullName) 
    { 
    } 

    public Context(string connectionString, string mappingId) 
     : this(VfpQueryProvider.Create(connectionString, mappingId)) 
    { 
    } 

    public Context(VfpQueryProvider provider) 
     : base(provider) 
    { 
    } 

    public virtual IEntityTable<MyTable> MyTables 
    { 
     get { return this.GetTable<MyTable>(); } 
    } 
} 

您定义上下文属性是这样的:

public partial class ContextAttributes : Context 
{ 
    public ContextAttributes(string connectionString) 
     : base(connectionString) { 
    } 

    [Table(Name="mytable")] 
    [Column(Member="ID", IsPrimaryKey=true)] 
    [Column(Member="Field1")] 
    [Column(Member="Field2")] 
    [Column(Member="Field3")] 
    public override IEntityTable<MyTable> MyTables 
    { 
     get { return base.MyTables; } 
    } 
} 

你还需要一个连接字符串,你可以像这样在app.config中定义它(Data\相对路径被用作DBF文件,在这种情况下,源):

<connectionStrings> 
    <add name="VfpData" providerName="System.Data.OleDb" 
    connectionString="Provider=VFPOLEDB.1;Data Source=Data\;"/> 
</connectionStrings> 

最后,您可以执行读取和写入,并从DBF作为文件一样简单:

// Construct a new context 
var context = new Context(ConfigurationManager.ConnectionStrings["VfpData"].ConnectionString); 

// Write to MyTable.dbf 
var my = new MyTable 
{ 
    ID = 1, 
    Field1 = 10, 
    Field2 = "foo", 
    Field3 = "bar" 
} 
context.MyTables.Insert(my); 

// Read from MyTable.dbf 
Console.WriteLine("Count: " + context.MyTables.Count()); 
foreach (var o in context.MyTables) 
{ 
    Console.WriteLine(o.Field2 + " " + o.Field3); 
} 
+1

有趣的方法,下次我需要这个时,我会研究它。 Fala ti susjed。 Živio! ;) – watbywbarif 2012-05-08 06:17:18