views:

366

answers:

2

Update2 okay, i was able to get it to work, but i think there is a problem having two different datareaders whiles within another. after moving it out of the outer while in a method it works. The Exception from the 1st update was because i didn't closed the reader, so it opened too many tables an JET crashed on the 2048 open tables. So but i'm not very pleased with the result, but at least the data comes out.

I think for MDB purposes in C# it's maybe better to use the good old ADODB COM Wrapper which has been proven to do it's job.

Thanks to all your comments.

Update After I moved it into a method i get now this exception:

at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
   at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.OleDb.OleDbConnection.Open()
   at getMoney(String card, String field)Unspecified errorMicrosoft JET Database Engine

When I try to use in my ASPX Webpage in the Code Behind this:

try
{                   
    while()
    {
        ...
        db.Open();
        readDataMoney = new OleDbCommand("SELECT * FROM Customer WHERE card = '" + customer.card + "';", db).ExecuteReader();
        while (readDataMoney.Read())
        {
            try
            {
                if (!readDataMoney.IsDBNull(readDataMoney.GetOrdinal("Credit")))
                {
                    customer.credit = Convert.ToDouble(readDataMoney[readDataMoney.GetOrdinal("Credit")]);
                }
                if (!readDataMoney.IsDBNull(readDataMoney.GetOrdinal("Bonus")))
                {
                    customer.bonus = Convert.ToDouble(readDataMoney[readDataMoney.GetOrdinal("Bonus")]);
                }
            }
            catch (Exception ex)
            {
                //Connector.writeLog("Money: " + ex.StackTrace + "" + ex.Message + "" + ex.Source);
                customer.credit = 0.0;
                customer.credit = 0.0;
                continue;
            }
            finally { }
        }
        readDataMoney.Close();
        db.Close();
        ...
    }
}
catch
{
    continue;
}

The whole page hangs if there is a problem when the read from db isn't working. I tried to check for !isNull, but same problem. I have a lots of differend MDB Files to process, which are readonly (can't repair/compact) and some or others not. Same Design/Layout of Tables. With good old ASP Classic 3.0 all of them are processing with the "On Resume Next". I know I know. But that's how it is. Can't change the source. So the basic question:

So is there any way to tell .NET to continue the loop whatever happens within the try loop if there is any exception?

After a lots of wating time i get this exceptions:

    at System.Data.Common.UnsafeNativeMethods.IDBInitializeInitialize.Invoke(IntPtr pThis)
   at System.Data.OleDb.DataSourceWrapper.InitializeAndCreateSession(OleDbConnectionString constr, SessionWrapper& sessionWrapper)   at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
   at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.OleDb.OleDbConnection.Open()
   at GetCustomer(String card)Thread was being aborted.System.Data

and

System.Runtime.InteropServices.Marshal.ReadInt16(IntPtr ptr, Int32 ofs) 
System.Data.ProviderBase.DbBuffer.ReadInt16(Int32 offset) 
System.Data.OleDb.ColumnBinding.Value_I2() 
System.Data.OleDb.ColumnBinding.Value() 
System.Data.OleDb.OleDbDataReader.GetValue(Int32 ordinal) 
System.Data.OleDb.OleDbDataReader.get_Item(Int32 index) 
Thread was terminated.mscorlib 

Thanks for any help.

A: 

It looks like it's catching an exception on the last record in the file and then, because end-of-file has already been reached, it just keeps throwing an exception and continueing, over and over again.

I suspect that you don't need two continue statements, but only one (the inside one).

You should rewrite this in a way that doesn't require an exception to control the program flow.

Robert Harvey
oh, sounds good, but how to avoid or handle it.it's only one or none. card id is unique.
csharpnoob
Check reader.IsEof, or other similar property that returs if the end of file was reached.
Carlos Loth
Try removing both `continue` statements and the outside `try/catch`, and see what happens.
Robert Harvey
@Carlos: I think he's already doing that with the `while (readDataMoney.Read())`.
Robert Harvey
@Robert you are right, I was not sure if it the read was doing that or not, thanks for the clarification.
Carlos Loth
@Robert: I changed code and moved try/catch out of the while. But same result.System.Data.Common.SafeNativeMethods.SetErrorInfo(Int32 dwReserved, IntPtr pIErrorInfo)Strange thing still to me is. Why is it working on some db's and some not. I just want .NET to continue the loop and not to terminate the thread.The try should be better within the loop, otherwise it's if i want to have more exception logicon seperate fields it won't be possible.
csharpnoob
A: 

I noticed that inside the catch block you do this:

Connector.writeLog(...

What class is Connector, and what does it do inside writeLog? Does it attempt to write the error information to a table in a database, or does it write to a file or the event log or something else?

Also, this is probably a typo, but in your code sample you close a different connection (vsiDB) than the one you open (db).

MusiGenesis
Connector writeLog does only write a txt file, the db thing is a copy and paste mistake, connection is fine.
csharpnoob