简体   繁体   English

如何在C#中确定现有的oracle数据库连接?

[英]How to determine an existing oracle database connection in C#?

Assuming that I call the method below with the right credentials: 假设我使用正确的凭据调用以下方法:

private bool Connect(string username, string password)
    {
        string CONNSTRING = "Provider = MSDAORA; Data Source = ISDQA; User ID = {0}; Password = {1};";
        OleDbConnection conn = new OleDbConnection();
        string strCon = string.Format(CONNSTRING, username, password);
        conn.ConnectionString = strCon;
        bool isConnected = false;

        try
        {
            conn.Open();

            if (conn.State.ToString() == "Open")
                isConnected = true;
        }//try
        catch (Exception ex)
        {
            lblErr.Text = "Connection error";
        }//catch
        finally
        {
            conn.Close();
        }//finally

        return isConnected;
    }

I have successfully open the connection in my method below: 我已经在下面的方法中成功打开了连接:

private bool ValidateUserCode(string usercode)
{
    UserAccountDefine def = new UserAccountDefine();
    UserAccountService srvc = new UserAccountService();
    UserAccountObj obj = new UserAccountObj();

    bool returnVal = false;
    bool isValid = Connect(def.DB_DUMMY_USERCODE, def.DB_DUMMY_PASSWORD);
    if (isValid)
    {
        obj.SQLQuery = string.Format(def.SQL_LOGIN, usercode.ToLower(), DateTime.Now.ToString("MM/dd/yyy"));
        DataTable dt = srvc.Execute(obj, CRUD.READALL);
        if (dt.Rows.Count == 1)
        {
            returnVal = true;
        }
    }
    return returnVal;
}

The question is how can I determine the connection status in ValidateUserCode() method? 问题是如何确定ValidateUserCode()方法中的连接状态? How can I close it afterwards? 之后如何关闭它?

Note: I explicitly declare the string variables in UserAccountDefine(); 注意:我在UserAccountDefine();明确声明了字符串变量UserAccountDefine(); so you don't have to worry about that. 因此您不必为此担心。

I already tried declaring a new OleDbConnection conn inside the ValidateUserCode() to but the conn.State always returning "Closed" . 我已经尝试在ValidateUserCode()声明一个新的OleDbConnection conn ,但是conn.State总是返回"Closed"

UPDATE UPDATE

I have a system with 2-layer security feature. 我有一个具有2层安全功能的系统。 1st is in application and 2nd is on database. 第一个在应用程序中,第二个在数据库中。 If a user logs in to the application, the username and password is also used to log him/her in to the database . 如果用户登录到该应用程序,则还使用用户名和密码登录他/她到数据库 Now, the scenario is when a user forgot his/her password, we can't determine the fullname , email and contact (which are maintained in the database) of the user. 现在,方案是当用户忘记密码时,我们无法确定用户的fullnameemailcontact (在数据库中维护)。 I just know his usercode . 我只知道他的用户usercode To determine the contact details, I have to open an active connection using a DUMMY_ACCOUNT . 要确定联系方式,我必须使用DUMMY_ACCOUNT打开活动连接。

Note that I never maintain the password inside the database. 请注意,我从不维护数据库内部的密码。

I am not sure how this information helps you. 我不确定这些信息如何为您提供帮助。

I had similar problem while using OLEDB connection for Excel Reading. 使用OLEDB连接进行Excel阅读时,我遇到了类似的问题。 I didn't knew the answer. 我不知道答案。 So, just I added a global variable for OleDbConnection initialized to null. 因此,只需为OleDbConnection添加一个全局变量,并将其初始化为null。

In my method, I used to check that null, if not close it and again open it. 在我的方法中,我曾经检查过是否为null(如果未关闭),然后再次将其打开。

        if (con != null)
        {
            con.Close();
            con.Dispose();
        }

        try
        {
            con = new OleDbConnection(connectionString);
        }
        catch (Exception ex)
        {
            MessageBox.Show("oledbConnection = " + ex.Message);
        }

        try
        {
            con.Open();
        }
        catch (Exception ex)
        {
            MessageBox.Show("connection open = " + ex.Message + "\n");
        }

I could able to continue after this. 之后,我可以继续。 You can try, if it works for you its good! 您可以尝试,如果对您有用,那么它很好!

First of all, you call Close() in your finally block, which means that at any point in your second method, the connection would be closed. 首先,您在finally块中调用Close() ,这意味着在第二个方法中的任何时候,连接都会关闭。 Moreover, even if you don't Close() it,since conn is a local variable in Connect() , when you're back in ValidateUserCode() , the connection is already up for garbage collection, and when it's Dispose() d, it also closes automatically. 而且,即使您不Close()它,因为connConnect()的局部变量,当您返回ValidateUserCode() ,该连接已经可以进行垃圾回收了,而当它是Dispose() ,它也会自动关闭。

I sugges you either make it a member, pass it as an out parameter, return it by the Connect() method (and return null for failure, or something, if you don't like exceptions)..or redesign the code. 我建议您要么使其成为成员,将其作为out参数传递,再通过Connect()方法Connect()其返回Connect()如果失败则返回null ,或者如果您不喜欢异常则返回null )。或者重新设计代码。

private OleDbConnection Connect(string username, string password)
{
    string CONNSTRING = "Provider = MSDAORA; Data Source = ISDQA; User ID = {0}; Password = {1};";
    OleDbConnection conn = new OleDbConnection();
    string strCon = string.Format(CONNSTRING, username, password);
    conn.ConnectionString = strCon;

    try
    {
        conn.Open();

        if (conn.State.ToString() == "Open")
            return conn;
    }//try
    catch (Exception ex)
    {
        lblErr.Text = "Connection error";
    }//catch
    finally
    {
        //you don't want to close it here
        //conn.Close();
    }//finally

    return null;
}

I'm not sure I follow the question quite right. 我不确定我是否完全正确地回答了这个问题。 My answer is based on the premise that you want to open/retrieve a connection, take an action, and close/release the connection afterward. 我的回答基于您要先打开/检索连接,执行操作并随后关闭/释放连接的前提。

The code you include does not do that well. 您包含的代码效果不佳。 Typical DAO code resembles this pseudocode, in my case taken from some boilerplate code I use. 在我的情况下,典型的DAO代码类似于此伪代码,摘自我使用的一些样板代码。

public DataSet FetchDataSet(string sql, IDictionary paramHash) {
    var cnn = AcquireConnection();
    var rtnDS = new DataSet();
    try
    {
        var cmd = cnn.CreateCommand();
        cmd.CommandText = sql;

        SetParameters(cmd, paramHash);
        IDbDataAdapter ida = new DataAdapter { SelectCommand = cmd };
        LogSql(sql, paramHash, "FetchDataSet");
        ida.Fill(rtnDS);
    }
    catch (Exception ex)
    {
        DebugWriteLn("Failed to get a value from the db.", ex);
        throw;
    }
    finally
    {
        ReleaseConnection(cnn);
    }
    return rtnDS;
}

Note that the code above is strictly about communicating with the database. 请注意,上面的代码严格来说是与数据库通信的。 There is no assessment of whether the data is right or wrong. 无法评估数据是对还是错。 You might have a DAO that is a subclass of the one that contains the above code, and it might do this: 您可能有一个DAO,它是包含上述代码的DAO的子类,并且它可以这样做:

public MyItemType FindSomeValue(long Id)
{
    const string sql = @"SELECT something from somewhere where id=:id";
    var myParams = new Dictionary<string, long> { { "id", Id } };
    var ds = FetchDataSet(sql, myParams);

    return (from DataRow row in ds.Tables[0].Rows
            select new Item
            {
                Id = Convert.ToInt64(row["ID"], CultureInfo.InvariantCulture),
                Name = row["NAME"].ToString()
            }).FirstOrDefault();
}

In fact, the above is pseudocode from a DAO implementation that I've used for years. 实际上,以上是我使用多年的DAO实现的伪代码。 It makes data access relatively painless. 它使数据访问相对轻松。 Note that there is some real code behind those methods like SetParameters (30 - 80 lines or so), and I have a bunch of other protected methods like FetchScalar, ExecuteSQL, etc. 请注意,这些方法后面有一些实际代码,例如SetParameters(大约30-80行),并且我还有很多其他受保护的方法,例如FetchScalar,ExecuteSQL等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM