مسألة الميراث - استرجاع البيانات من ملف قاعدة بيانات Access و SQL اكسبرس

StackOverflow https://stackoverflow.com/questions/256027

سؤال

وأنا تطوير تطبيق والتي سوف تكون متصلا الوصول إلى قاعدة البيانات في البداية وهذه الخطة هو التحول إلى MS SQL أو SQL Express في المستقبل القريب. الهياكل datatables هي نفسها لكلا النوعين من قواعد البيانات واني اسعى الى تجنب تكرار رمز ومحاولة للعثور على طريقة للحد من التعليمات البرمجية.

وعلى سبيل المثال كتبت الدالة التالية لاسترجاع البيانات من قاعدة بيانات Access:

public static DataTable GetActiveCalls()
    {
        string select = "SELECT call_id, call_time, msisdn, status FROM call WHERE status = 0 OR status = 1 ORDER by call_id ASC";
        OleDbCommand cmd = new OleDbCommand(select, conn);
        DataTable dt = new DataTable("Active Calls");
        OleDbDataAdapter DA = new OleDbDataAdapter(cmd);
        try
        {
            conn.Open();
            DA.Fill(dt);
        }
        catch (Exception ex)
        {
            string sDummy = ex.ToString();
        }
        finally
        {
            conn.Close();
        }
        return dt;
    }

ووالبرمجية التالية لقاعدة بيانات SQL اكسبرس:

public static DataTable GetActiveCalls()
    {
        string select = "SELECT call_id, call_time, msisdn, status FROM call WHERE status = 0 OR status = 1 ORDER by call_id ASC";
        SqlCommand cmd = new SqlCommand(select, conn);
        DataTable dt = new DataTable("Active Calls");
        SqlDataAdapter DA = new SqlDataAdapter(cmd);
        try
        {
            conn.Open();
            DA.Fill(dt);
        }
        catch (Exception ex)
        {
            string sDummy = ex.ToString();
        }
        finally
        {
            conn.Close();
        }
        return dt;
    }

وهذه الطريقتين هي نفسها تقريبا. الاختلافات الوحيدة هي SqlCommand / OleDbCommand وSqlDataAdapter / OleDbDataAdapter. وهناك أيضا بعض الأساليب التي تأخذ الحجج على سبيل المثال:

public static void AddMessage(string callID, string content)
    {
        string select =
            "INSERT INTO message(key, direction, content, read, write_time) VALUES (@callId, 0, @content, 0, @insertTime)";
        OleDbCommand cmd = new OleDbCommand(select, conn);
        cmd.Parameters.AddWithValue("callId", callID.ToString());
        cmd.Parameters.AddWithValue("content", content);
        cmd.Parameters.AddWithValue("insertTime", DateTime.Now.ToString());
        try
        {
            conn.Open();
            cmd.ExecuteScalar();
        }
        catch (Exception ex)
        {
            string sDummy = ex.ToString();
        }
        finally
        {
            conn.Close();
        }
    }

في هذه السلسلة الاستعلام حالة SQL هو أيضا الشيء نفسه بالنسبة لقواعد البيانات على حد سواء ولكن هناك فرق بين نوع من كمد (SqlCommand / OleDbCommand).

وسأكون ممتنا حقا إذا كان أي شخص يمكن أن يعطي أي اقتراح حول كيفية تجنب تكرار رمز وتحسين مشكلة معينة.

هل كانت مفيدة؟

المحلول

ويمكنك استخدام واجهات قاعدة بيانات مستقلة IDbDataAdapter وIDbCommand، ومن ثم خلق حالات محددة باستخدام المصنع. هنا مثال على ذلك.

ولكن أود أن ريككوميند باستخدام محلول ORM مثل NHibernate إذا كان التطبيق الخاص بك ليست بسيط جدا، لأن هناك اختلافات صغيرة في لغة SQL بين الوصول و SQL Server التي يمكن أن تجعل رمز وصول البيانات الخاصة بك أكثر تعقيدا.

نصائح أخرى

ويجب أن نلقي نظرة على بت الوصول إلى البيانات و مكتبة المؤسسة . وتستخرج خصوصيات مزود قاعدة البيانات الأساسية بعيدا عنك. على سبيل المثال:

string sql = @"UPDATE tblContent 
                        SET Title = @Title, Content = @Content, IsPublic = @IsPublic, ItemOrder = @ItemOrder
                        WHERE ContentItemID = @ContentItemID";

Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
    db.AddInParameter(cmd, "Title", DbType.String, title);
    db.AddInParameter(cmd, "Content", DbType.String, content);
    db.AddInParameter(cmd, "IsPublic", DbType.Boolean, isPublic);
    db.AddInParameter(cmd, "ItemOrder", DbType.Int32, itemOrder);
    db.AddInParameter(cmd, "ContentItemID", DbType.Int32 , contentItemID);

    db.ExecuteNonQuery(cmd);
}

... أو ...

string sql = "SELECT MenuText FROM tblMenuItems WHERE MenuItemID = @MenuItemID";

Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
    db.AddInParameter(cmd, "MenuItemID", DbType.Int32, menuItemID);

    using(IDataReader dr = db.ExecuteReader(cmd))
    {
        while(dr.Read())
        {
            return dr["MenuText"].ToString();
        }
        return null;
    }
}

وكل من الأمثلة أعلاه العمل مع Access و MS SQL وشريطة أن التمسك البيانات SQL التي تتوافق مع كل من Jet و MS SQL يجب أن لا يكون أي مشاكل.

وعند التبديل من الوصول إلى MS SQL مجرد تغيير سلسلة الاتصال، على سبيل المثال، من:

<connectionStrings>
    <add 
         name="ContentManager" 
         connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Content.mdb;" 
         providerName="System.Data.OleDb"/>
</connectionStrings>

و... إلى ...

<connectionStrings>
    <add
        name="ContentManager"
        connectionString="Data Source=your.sql.server;Initial Catalog=content;Persist Security Info=True;User ID=cmuser;Password=password"
        providerName="System.Data.SqlClient" />
</connectionStrings>

لتحقيق ذلك تحتاج فقط إلى مرجع التالية في DLL في توزيع EL:

وMicrosoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.EnterpriseLibrary.Data.dll

وتستحق نظرة.

وهتاف
كيلو

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top