Вопрос о наследовании - получение данных из файла базы данных Access и SQL Express - PullRequest
1 голос
/ 01 ноября 2008

Я разрабатываю приложение, которое вначале будет подключено к базе данных Access, и в ближайшем будущем планируется перейти на 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 Express:

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 также одинакова для обеих баз данных, но есть разница между типом cmd (SqlCommand / OleDbCommand).

Буду очень признателен, если кто-нибудь подскажет, как избежать дублирования кода и оптимизировать данную проблему.

Ответы [ 2 ]

1 голос
/ 02 ноября 2008

Обратите внимание на биты доступа к данным Enterprise Library . Специфика основного поставщика базы данных абстрагируется для вас. Например:

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, у вас не должно возникнуть никаких проблем.

При переключении с Access на 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

Стоит посмотреть.

Приветствия
Кев

1 голос
/ 01 ноября 2008

Вы можете использовать независимые от базы данных интерфейсы IDbDataAdapter и IDbCommand, а затем создавать конкретные экземпляры с использованием фабрики. Здесь является примером.

Однако я бы рекомендовал использовать решение ORM, такое как NHibernate , если ваше приложение не очень простое, потому что существуют небольшие различия в языке SQL между Access и SQL Server, которые могут сделать ваш код доступа к данным более сложным .

...