Optimal way to handle .dbf from C#
Asked Answered
T

4

1

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!

Theo answered 8/7, 2010 at 16:49 Comment(0)
M
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);
}
Moniquemonism answered 8/5, 2012 at 5:7 Comment(1)
Interesting approach, I'll look into it next time I need this. Fala ti susjed. Živio! ;)Theo
S
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.

Sempiternal answered 12/7, 2010 at 11:49 Comment(0)
B
0

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?

Bloodstained answered 8/7, 2010 at 17:7 Comment(1)
Yes, but update is too slow. I have ~1GB base, and i have to purge some characters from each row that contains it. If i do it row by row it takes too much because db is not indexed. I have to do some ugly thing like get all to memory, delete all records and replace by changed records. I tried update with replace command but it seems that Microsoft JET does not support it. Maybe some other provider does? Now i succeeded update with replace from Access, but i am not sure what is access using?Theo
T
0

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

Triton answered 8/7, 2010 at 17:8 Comment(1)
I found this by following links on pages you recommended: c-sharpcorner.com/uploadfile/rfederico/… It looks promising, ill give it a try some other day.Theo

© 2022 - 2024 — McMap. All rights reserved.