How can we migrate the DBF related code to C#.NET? - c#

I have a code related to dbf operation in Visual foxpro as given below .
SELECT 3
USE student shared
SET FILTER TO
LOCATE FOR id=thisform.txtStudentID.Value
can any one help me to understand the each line of code and convert to C#.net.What are the steps to be taken to convert foxpro code to C# ? Here I am using SQL Server as backend in C# Project.Some times I have faced the below type of code also
Use Student Shared
// Here accessing the database fields directly.Here Are they targeting to get all records like "select * from student" or only last record.By default this student table has 6 columns but in the dbf file we have 12 columns. How can do this in C#.NET?

To answer part of your question - what does this code do...
The following sets a work area (I haven't done foxpro for a few years now, but think this is redundant in the later versions of VFP). A work area is just a space in memory which is kept sperate from other work spaces.
Select 3
The following opens a table called 'Student' for non-readonly access into the previously opened workspace
USE student shared
The following clears all filters on the table (so if you 'BROWSE' you will get all records)
SET FILTER TO
The following will set the record pointer to a specific record where the record with an id is equal to the txtStudentID textbox value on the current form (foxpro is not a strongly typed language)
LOCATE FOR id=thisform.txtStudentID.Value
For the second part of your question, there is no direct way to convert between foxpro and a c# application. The main points are that Foxpro is built around a database and is not strongly typed whereas c# is stongly typed and can access a database. If you do a quick google search you will probably find tools written by people like Markus Egger to convert from foxpro to c#.
IMHO and from experience of migrating an enterprise sized system from VFP to c# / SQL server - if you want to do this with a system - stop, convince yourself it is a bad idea and just re-write the thing in c# - picking a database that best suits your needs.
It's hard to comment further - you haven't stated what version of foxpro you are using - are you using foxpro or visual foxpro? What size is your application, what is the background?
HTH
Jay

There is no way to directly convert that to C#.
SELECT 3
FoxPro has the concept of 'work areas' - like slots, each of which can have an opened DBF file in it. This command says "OK - we're looking at work area 3."
This has no equivalent in .NET
USE student SHARED
This will open student.dbf, in the current directory, for shared access in work area 3.
SET FILTER TO
If we have a filter set, which will limit what records are available, clear that filter now. Pointless, as we've just opened the table and we didn't set a filter.
LOCATE FOR id=thisform.txtStudentID.Value
Find the first record where id = thisform.txtStudentID.Value. The latter part is a custom property of the form that is running this code.
So all this code is doing is locating a record in student.dbf based on a value. If you wanted to pull that record back in C# using the OLE DB provider you could check How to load DBF data into a DataTable.

The SET FILTER TO is not needed as the table is being used (opened) so there is no filter to clear. To convert this bit of FoxPro to C#:
SELECT * FROM student WHERE id=thisform.txtStudentID.Value
You would then have to loop the results (if any). Best practices would be to use a parameter for the WHERE clause value to prevent SQL injection.

Related

C# Microsoft.Data.Analysis Dataframe to SQL Server

I want to load my Microsoft.Data.Analysis Dataframe into a SQL Server table. I somehow learnt that I should use Entity Framework for that, but I haven't found a solution similar to Pythons Sqlalchemy pandas.dataframe.tosql() method. Is there an easy way to achieve that?
I've already tried Googling that of course, but sadly that did not lead to any results, is it possible at all?
Thanks in advance for any help and have a lovely day
Right now, no. The Microsoft.Data.Analysis namespace is somewhat ... aspirational and can't even be used to load data from a database. It's an attempt to create something like Pandas Dataframes in the future and has nothing at all to do with Entity Framework.
If you want a DataFrame-like type in .NET, check the Deedle library which is used in F# data analysis programming.
Another option is to keep using Python, or learn Python, Pandas and Notebooks. Even Visual Studio Code and Azure Data Studio offer better support for Pandas and Notebooks than Microsoft.Data.Analysis.
The problem is that until recently Microsoft put all its effort in ML, not analysis. And Microsoft.Data.Analysis is part of the ML repository, so it got little attention since its introduction 2 years ago.
This changed on March 2022, when the DataFrame (Microsoft.Data.Analysis) Tracking Issue was created to track and prioritize what programmers wanted from a .NET Dataframe type. Loading from a database is open for 2 years without progress.
Loading from SQL
If you want to use Microsoft.Data.Analysis.DataFrame right now you'll have to write code similar to the CSV loading code:
Create a list of DataFrameColumns from a DataReader's schema. This can be retrieved with DbDataReader.GetSchemaTable.
Create a DataFrame with those columns
For each row, append the list of values to the dataframe. The values could be retrieved with DbDataReader.GetValues
Loading from Excel
The same technique can be used if the Excel file is loaded using a library like ExcelDataReader that exposed the data through a DataReader. The library doesn't implement all methods though, so some tweaking may be needed if eg GetValues doesn't work.
Writing to SQL
That's harder because you can't just send a stream of rows to a table. A DataFrame is a collection of Series too, not rows. You'd have to construct the INSERT SQL command from the column names, then execute it with data from each row.
A dirty way would be to convert the DataFrame into a DataTable and save that using a DataAdapter. That would create yet another copy of the data in memory though.
A better way would be to create a DataReader wrapper over a DataFrame, and pass that reader to eg SqlBulkCopy

How do I get the trigger_body from the user-triggers table in C#

Background: I'm actually trying to identify autoincrement columns in an Oracle table from a C# program. I have already discovered that in Oracle autoincrement is done using a sequence and a trigger, and have identified the sequences and triggers in an example database using SQL Developer.
So, next step, get the triggers: this I can do with a query - "Select * from USER_TRIGGERS". No problem. There is even a TABLE_NAME field to check against the table I want to examine. (There is also a COLUMN_NAME column which might be useful, but that always seems to be empty).
Now there seems to be no alternative but to parse the TRIGGER_BODY field - but there's the rub. SQL Developer shows me that there is a meaningful-looking string in TRIGGER_BODY, but in my DataTable, returned from the query, the TRIGGER_BODY field is always blank.
I've hunted around on the web, and it seems that TRIGGER_BODY is in fact a LONG, although C# says the column is of type string, so I don't understand that. The only suggestion I've found so far is to use the TO_LOB() (or possibly TO_CLOB()) function to somehow convert the contents of the field, however that just throws an "inconsistent datatypes" exception.
I'm using C# 4.5, and Oracle.DataAccess for the data access objects. Oracle is at Version 11g.
Any suggestions would be gratefully received.
Once you have the owner and name of your trigger from dba_|all_|user_triggers, the easiest option is generally to use the dbms_metadata package to generate the DDL to create the trigger. That will be a CLOB that your front end should be able to work with.
DBMS_METADATA.GET_DDL('TRIGGER', <<name of trigger>>, <<owner of trigger>> )
Unfortunately, the LONG data type in Oracle was a very short-lived dead end data type. It was introduced some time in the Oracle 7 days if memory serves and was depricated by 8.1.5 in favor of the CLOB (BLOB for the depricated LONG RAW). Oracle has been recommending that people not use that data type for roughly 20 years. There are a whole host of restrictions on working with this data type. For the most part, it only exists in very old legacy apps and in the data dictionary tables where it was added since Oracle wants to ensure backwards compatibility of those views. Most front end tools today don't build in support for LONG data types because at the OCI layer it involves jumping through quite a few hoops that you only have to jump through to work with a LONG.

Data transfer from One database to another

I am looking for an idea or some direction. I have to transfer data from one database to another both are structurally and schema wise same.
Its a complete database with maybe 70 tables and having relationship between tables at different levels. Even though i ' m going to mess up the identity when i move across database but as of now i am ok with it.
Idea which i thought was to load required data from all table into an XML and then create connection to second database and push data from this XML its kind of repeated and not best way at all. So looking for direction.
Can i use entity framework for this somehow??
I cannot use SSIS for this it has to be C# Sorry.
You can create a linked server as stated in the comments to your question. You seemed to indicate that you know how to do this, but in case not, you can do this from SQL Server Management Studio by drilling down to "Server Objects > Linked Servers" beneath your source database on the source database server, then right-click, "New Linked Server", etc.
Then you would use a statement like this, for example, from your C# code:
insert into DestServer.DBName.dbo.TableName
select * from SourceServer.DBName.dbo.TableName
Assuming you are connected to 'SourceServer' and that 'SourceServer' maintains a linked server object pointing to 'DestServer'. Note: you don't actually need to use the fully-qualified name for the table on 'SourceServer', but I've put it there for clarity. I.E. you could also do this:
insert into DestServer.DBName.dbo.TableName
select * from TableName
Don't forget to setup the permissions properly in your linked server object so that your query can write to the table in the destination server. You can do this any number of ways, and often (because I work in a small environment where it's maintained by just me and a couple other folks) I just use the "sa" login:
Yes, can use linked servers in .NET.
You just use the 4 part name.
What you can do in TSQL in SSMS you can do in a .NET SQLcommand.
My experience is that you get better performance connecting to the server you are writing to.

Options for working with two databases in C#

Ok I`m new to C# and new to Programing. I have taken on a small task(goal) for writing my own program for work.
Basically this program will take two databases. One data base will be update weekly (lets call this doctor list) and the other data base will be updated as needed (lets call this employee).
Basically I want to make my program compare the two databases and look for any matching employees on this list doctor list.
I can figure out the code for the searching and basic stuff.. But I have no clue where to begin with databases.
I'm ok with SQL but my problem is that my doctor list comes in a dbf file. I've looked up converting to access and sql but this program needs to be easy to use for our hr department.
Is there away to write the conversion? (again new to this)
What kind of options do I have with just working with programing it to read off an excel sheet?
If I do go the access or sql route do the computers this program run off of need to have access or sql installed?
I`m not looking for someone to write me the code.. just point me in a good directions and answer some questions...
To convert the database to SQL you'll need a third party application.
I'd check out: http://www.whitetown.com/dbf2sql/ because it includes the DLLs for use in your application as well when you buy the site license. If you're receiving a new database each time and need to transform it, that would be the way to go.
Your client should be the one accessing the database, which should (hopefully) be stored on a server. If it's a local database (so not multiple user based) then I'd recommend going SQLite as it's probably the best lightweight standalone database out there. You can also get a good ORM for SQL or SQLite (such as DrivenDB) to be able to access your data.
If you're going to stay in dbf format then you'll need to know if it's a VisualFox Pro, Dbase, etc. type of database and get the appropriate DLLs for accessing it.

Best way to incorporate legacy data

I am working on a price list management program for my business in C# (Prototype is in Win Forms but am thinking of using WPF for the final ap as a MVVM learning exercise).
Our EMS system is based on a COBOL back end and will remain that way for at least 3 years so I cannot really access it's data directly. I want to pull data from them EMS system periodically to ensure that pricing remains in sync (And to provide some other information to users in a non-editable manner such as bin locations). What I am looking at doing is...
Use WinBatch to automatically run a report nightly then to Use Monarch to convert the text report to a flat file (.xls?)
Drop the file into a folder and write a small ap to read it in and add it to the database
How should I add this to the database? (SQL Express) I could have a table that is just replaced completely each time but I am a beginner at most of this and I am concerned what would happen if an entire table was replaced while the database was being used by the price list ap.
Mike
If you truncate and refill a whole table you should do it in one single transaction and place a full table lock. This is more secure and faster.
You also could update all changed rows, then insert new (missing rows) and then delete all rows which weren't updated in this run (insert some kind of version number in each row to determine this).
First create a .txt file from the legacy application. Then use a batch insert to pull it into a work table for whatever clean up you need to make. Do the clean up using t-sql. Then run t-sql to insert new data into the proper tables and/or to update rows where data has changed. If there are toomany records, do the inserting and updating in batches. Schedule all this as a job to run during hours when the database is not busy.
You can of course do all of this best in SSIS but I don't know if that is available with Express.
Are there any fields/tables available to tell you when the price was last updated? If so you can just pull the recently updated rows and update that in your database.... assuming you have a readily available unique primary key in your cobol app's datastore.
This wouldn't be up to date though because you're running it as a nightly script to update the database used by the new app. You can maybe create a .net script to query the cobol datastore specifically for whatever price the user is looking for, and if the cobol datastores update time is more recent than what you have logged, update the SQL Server record(s).
(I'm not familiar with cobol at all, just throwing ideas out there)

Categories