Implementare Generic DataSet Builder con C #

1

Voglio creare una libreria di accesso ai dati in grado di creare un DataSet con relazioni che possono essere facilmente scritte in XML con dataset.WriteXML() . Questo è uno spunto per conoscere l'impresa C # che, si spera, mi darà anche un po 'di produttività (molte conversioni di tabelle relazionali in XML da diverse fonti di dati per la generazione di documenti)

Finora l'unica differenza che vedo tra le tecnologie di accesso ai dati (SQL, OLEDB, ODBC) riguardo a come le userò per questo è che richiedono un tipo specificato di connessione e adattatore (SqlAdapter, OleDbAdapter, OdbcAdapter, ecc. ).

Quindi nella mia mente immagino classi con due metodi e un set di dati pubblici che sarà riempito.

public DataSet DataSet { get; set; }

public void InsertTables(string ConnectionString, string[] TableNames, string[] Commands)

public void AddRelations(string[] PrimaryTables, string[] PrimaryKeys, string[] ChildTables, string[] ForeignKeys, bool[] NestingRules)

Ho già iniziato con un'implementazione OleDb che funziona bene e voglio impostare qualcosa di simile per altre tecnologie di accesso ai dati. Tuttavia, voglio essere il più efficiente possibile con il codice, quindi sono alla ricerca di consigli su come ottenere.

Stavo pensando che il modello di Template Method Design potrebbe essere un approccio solido, ma poi ho anche pensato che una singola classe che utilizza i generici potesse funzionare altrettanto bene (sono nuovo di C # e non mi è familiare).

Sto cercando un esempio generale di come potrei ottenere questo risultato con un buon modello di progettazione e / o generici.

Ecco cosa ho per OleDbDesign. Qualsiasi consiglio è molto apprezzato.

 public class OleDbDataSetBuilder
{
    private DataSet _DataSet;

    public DataSet DataSet { get { return _DataSet; } }

    public OleDbDataSetBuilder(string DataSetName)
    {
        this._DataSet = new DataSet(DataSetName);
    }

    public void InsertTables(string ConnectionString, string[] TableNames, string[] Commands)
    {

        if (TableNames.Length != Commands.Length)
        {
            throw new Exception("Error: Must provide a table name for each command.");
        }

        OleDbConnection cn = new OleDbConnection(ConnectionString);

        OleDbDataAdapter adapter = new OleDbDataAdapter("", cn);

        adapter.SelectCommand = new OleDbCommand("", cn);

        for (int i = 0; i < TableNames.Length; i++)
        {
            adapter.SelectCommand.CommandText = Commands[i];

            adapter.Fill(_DataSet, TableNames[i]);
        }

        cn.Close();

    }

    public void AddRelations(string[] PrimaryTables, string[] PrimaryKeys, string[] ChildTables, string[] ForeignKeys, bool[] NestingRules)
    {

        for (int i = 0; i < PrimaryTables.Length; i++)
        {
            DataColumn pk = _DataSet.Tables[PrimaryTables[i]].Columns[PrimaryKeys[i]];

            DataColumn fk = _DataSet.Tables[ChildTables[i]].Columns[ForeignKeys[i]];

            DataRelation relation = _DataSet.Relations.Add(pk, fk);

            relation.Nested = NestingRules[i];
        }
    }
}
    
posta wesmantooth 03.07.2014 - 22:51
fonte

1 risposta

-1

Questo è un link che descrive questo approccio.

Di seguito è riportata la mia classe risultante sulla base del suggerimento di Dan

using System;
using System.Data;
using System.Data.Common;

namespace CustomDataAccess{

public class DataSetBuilder
{

    #region Properties

    private DataSet _DataSet;

    public DataSet DataSet { get { return _DataSet; } }

    #endregion

    #region Constructors

    public DataSetBuilder()
    {
        this._DataSet = new DataSet();
    }

    public DataSetBuilder(string DataSetName)
    {
        this._DataSet = new DataSet(DataSetName);
    }

    public DataSetBuilder(DataSet DataSet)
    {
        this._DataSet = DataSet;
    }

    #endregion

    #region Public Methods

    public DataSetBuilder InsertTables(DataTable Table)
    {
        this._DataSet.Tables.Add(Table);

        return this;
    }

    public DataSetBuilder InsertTables(string DbProviderName, string ConnectionString, string TableName, string CommandText)
    {
        System.Data.Common.DbDataAdapter adapter = Create_Adapter(DbProviderName, ConnectionString);

        Fill_Adapter(adapter, TableName, CommandText);

        adapter.SelectCommand.Connection.Close();

        return this;
    }

    public DataSetBuilder InsertTables(string DbProviderName, string ConnectionString, string[] TableName, string[] CommandText)
    {
        if (TableName.Length != CommandText.Length)
        {
            throw new Exception("Error: Must provide a table name for each command.");
        }

        System.Data.Common.DbDataAdapter adapter = Create_Adapter(DbProviderName, ConnectionString);

        for (int i = 0; i < TableName.Length; i++)
        {

            Fill_Adapter(adapter, TableName[i], CommandText[i]);
        }

        adapter.SelectCommand.Connection.Close();

        return this;
    }

    public void AddRelations(string ParentTable, string PrimaryKey, string ChildTable, string ForeignKey, bool NestingRule)
    {
        Add_Relations(ParentTable, PrimaryKey, ChildTable, ForeignKey, NestingRule);
    }

    public void AddRelations(string[] ParentTable, string[] PrimaryKey, string[] ChildTable, string[] ForeignKey, bool[] NestingRule)
    {

        for (int i = 0; i < ParentTable.Length; i++)
        {
            Add_Relations(ParentTable[i], PrimaryKey[i], ChildTable[i], ForeignKey[i], NestingRule[i]);
        }
    }

    #endregion

    #region Private Methods

    private System.Data.Common.DbDataAdapter Create_Adapter(string DbProviderName, string ConnectionString)
    {
        DbProviderFactory dbFactory = System.Data.Common.DbProviderFactories.GetFactory(DbProviderName);

        System.Data.Common.DbConnection connection = dbFactory.CreateConnection();

        connection.ConnectionString = ConnectionString;

        connection.Open();

        System.Data.Common.DbCommand command = dbFactory.CreateCommand();

        command.Connection = connection;

        System.Data.Common.DbDataAdapter adapter = dbFactory.CreateDataAdapter();

        adapter.SelectCommand = command;

        return adapter;
    }

    private void Fill_Adapter(System.Data.Common.DbDataAdapter Adapter, string TableName, string CommandText)
    {
        Adapter.SelectCommand.CommandText = CommandText;

        Adapter.Fill(_DataSet, TableName);
    }

    private void Add_Relations(string ParentTable, string PrimaryKey, string ChildTable, string ForeignKey, bool NestingRule)
    {
        DataColumn pk = _DataSet.Tables[ParentTable].Columns[PrimaryKey];

        DataColumn fk = _DataSet.Tables[ChildTable].Columns[ForeignKey];

        DataRelation relation = _DataSet.Relations.Add(pk, fk);

        relation.Nested = NestingRule;
    }

    #endregion

}}
    
risposta data 04.07.2014 - 20:08
fonte

Leggi altre domande sui tag