Optimal way to handle .dbf from C#

丶灬走出姿态 提交于 2020-01-14 03:53:27

问题


What data-provider can I use to update .dbf file from C#?

I tried a few different .dbf providers to create a DataSource but I get a message like this: "Error Message: ERROR HYC00 Microsoft ODBC dBase Driver Optional feature not implemented."

Or when I generated a dataset and a dataadapter with an update function I got: "Update requires a valid UpdateCommand when passed DataRow collection with modified rows."

If anyone knows some way to work on .dbf from C# with lots of updates please help. When I try to update rows one by one it is too slow because the provider will lose too much time on searching a big .dbf file. Maybe there is a way to automatically build an index and that the data-source knows to use it?

Another way is to load all into something like dataset and update after all changes are done, but the update part is not working for now.

Help please!


回答1:


From your coment about ~1GB database, I too work with VFP Databases (.dbf) file formats, and SQL-Updates work no problem via OleDbCommand creation / execution, and can work with whatever native commands the VFP OleDbProvider runs.

For trying to remove some characters, I typically use the function CHRTRAN() (that is, if you DO use Visual Foxpro Ole DB Provider), where you can literally strip out many characters (such as invalid) something like...

Update YourTable
   set SomeField = chrtran( SomeField, "!@#$%^*(", "" )

will go through ALL records and strip any from the field (first parameter), any instance of individual character (2st parameter), and change it to the corresponding character found in the 3rd parameter... in this case, no value, just an empty string, so the characters would be stripped out. Quite fast in itself, and you don't have to keep scanning through all records being downloaded, tested, and then pushed back.

Again, not positive which native .DBF file system you are working with, but VFP is extremely fast with such manipulation.




回答2:


You can use LINQ to VFP to read from and write to DBF files. I use it to edit some dBase III files, works like charm.

You define your table to match the DBF definition like this:

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; }
}

You define the context like this:

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>(); }
    }
}

You define context attributes like this:

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; }
    }
}

You also need a connection string, you can define it in app.config like this (Data\ relative path is used as the source of DBF files in this case):

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

And finally, you can perform reading and writing to and from DBF files as simple as:

// 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);
}



回答3:


The vanilla OleDbConnection handles DBFs pretty well, if you stick with very basic SQL operations.

Here where I work, we build & maintain applications that interact with DBFs using exclusively OleDb classes. We do not, however, use Adapters or DataSources -- everything is done "directly" through OleDbCommands, OleDbDataReaders, and so on.

Perhaps DataAdapters rely on features that may not be present when interacting with basic or legacy data sources such as xBase. Have you tried using an UPDATE OleDbCommand?




回答4:


Usually,the FoxPro driver works with .DBF files. The file format is similar enough that this works well for reading. Writing is a bit more tricky. Unfortunately, since the DBASE is such an old technology, .NET doesn't play nice with it, so you're pretty much stuck with your slow option. Believe, me, I feel your pain as I have to work with these regularly for a POS system we support.

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?

and finally, my favorite source for Connection Strings:

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



来源:https://stackoverflow.com/questions/3206029/optimal-way-to-handle-dbf-from-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!