Cómo: Implementar una clase auxiliar JOIN de DataSet en Visual C# .NET

Seleccione idioma Seleccione idioma
Id. de artículo: 326080 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Resumen

Este artículo paso a paso describe cómo implementar y cómo utilizar una clase DataSetHelper que incluye código de ejemplo para crear un objeto DataTable desde dos o más definiciones relacionadas de la DataTable y copiar registros que están ordenados y filtrados desde los objetos DataTable de origen al destino DataTable .

Para ello, utilice los métodos públicos siguientes:
  • CreateJoinTable
  • InsertJoinInto
  • SelectJoinInto
El método SelectJoinInto llama a la CreateJoinTable y los métodos InsertJoinInto . También puede utilizar a un miembros de datos y el método auxiliar privado para almacenar la lista campo analizada.

La clase DataSetHelper incluye una variable de miembro de DataSet . Opcionalmente, puede asignar un DataSet existente a la variable de miembro de DataSet . Si la variable miembro apunta a un DataSet válido, los objetos DataTable que crea el CreateJoinTable o el método SelectJoinInto se agregan al DataSet . En cualquier caso, la llamada al método devuelve una referencia al objeto DataTable . El método de InsertJoinInto requiere un destino existente DataTable y no devuelve nada.

Para obtener más información acerca de los objetos DataSet , haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
313485INFO: Guía para DataSet, DataView y DataViewManager

Requisitos

En la lista siguiente se describe el hardware, el software, la infraestructura de red y los Service Packs recomendados que necesitará:
  • Microsoft Windows XP, Windows 2000 o Windows NT 4.0 Service Pack 6a
  • Microsoft Visual Studio .NET
En este artículo se supone que está familiarizado con los temas siguientes:
  • Sintaxis de Visual C# .NET
  • Fundamentos y sintaxis de ADO.NET

Clase DataSetHelper Shell

El código en esta sección declara la clase de shell para que todos los artículos de DataSetHelper agregar métodos y variables miembro.
  1. Inicie Visual Studio NET..
  2. En el menú archivo , seleccione nuevo y, a continuación, haga clic en proyecto .
  3. En el cuadro de diálogo Nuevo proyecto , haga clic en Proyectos de Visual C# en Tipos de proyecto y, a continuación, haga clic en Biblioteca de clases en plantillas .
  4. En el cuadro nombre , escriba DataSetHelper .
  5. Reemplace el código de la clase con el siguiente código:
    public class DataSetHelper
    {
        public DataSet ds;
    
        public DataSetHelper(ref DataSet DataSet)
        {
    	ds = DataSet;
        }
        public DataSetHelper()
        {
    	ds = null;
        }
    }
    					
    puede utilizar las dos sobrecargas del constructor para crear una instancia de la clase con o sin una referencia a un DataSet válido. Para una clase que contiene una referencia a un DataSet válido, los objetos DataTable que devuelven los métodos también se agregan automáticamente al DataSet .

Analizador de lista de campos

Esta sección contiene el código de un analizador de lista de campos. La estructura analizada se utiliza para que el CreateJoinTable y los métodos InsertJoinInto no tienen a la lista de campos de reanálisis. Estos métodos deben reanálisis la lista de campos si se llama a desde el método SelectJoinInto o desde su propio código. La lista de campos analizada y la lista de campos sin analizar se almacenan en variables de miembro privado de la clase DataSetHelper .
  1. Agregue la siguiente definición de clase privada a la clase DataSetHelper que creó en la sección "":
    private class FieldInfo
    {
        public string RelationName;
        public string FieldName;	//source table field name
        public string FieldAlias;	//destination table field name
        public string Aggregate;
    }
    					
    Nota : esta clase es común a otros artículos DataSetHelper y contiene algunos campos que no utilice este artículo.

  2. Agregue las siguientes variables miembro privadas a la definición de clase inmediatamente después de la declaración de DataSet :
    private System.Collections.ArrayList m_FieldInfo; private string m_FieldList; 
    					
  3. Agregue el siguiente método privado a la definición de clase. Este método es igual que el método que se utiliza en otros artículos DataSetHelper .
    private void ParseFieldList(string FieldList, bool AllowRelation)
    {
        /*
         * This code parses FieldList into FieldInfo objects  and then 
         * adds them to the m_FieldInfo private member
         * 
         * FieldList systax:  [relationname.]fieldname[ alias], ...
        */ 
        if (m_FieldList == FieldList) return;
        m_FieldInfo = new System.Collections.ArrayList();
        m_FieldList = FieldList;
        FieldInfo Field; string[] FieldParts;
        string[] Fields=FieldList.Split(',');
        int i;
        for (i=0; i<=Fields.Length-1; i++)
        {
            Field=new FieldInfo();
            //parse FieldAlias
            FieldParts = Fields[i].Trim().Split(' ');
            switch (FieldParts.Length)
            {
                case 1:
                    //to be set at the end of the loop
                    break;
                case 2:
                    Field.FieldAlias=FieldParts[1];
                    break;
                default:
                    throw new Exception("Too many spaces in field definition: '" + Fields[i] + "'.");	                        
            }
            //parse FieldName and RelationName
            FieldParts = FieldParts[0].Split('.');
            switch (FieldParts.Length)
            {
                case 1: 
                    Field.FieldName=FieldParts[0];
                    break;
                case 2:
                    if (AllowRelation==false)
                        throw new Exception("Relation specifiers not permitted in field list: '" + Fields[i] + "'.");
                    Field.RelationName = FieldParts[0].Trim();
                    Field.FieldName=FieldParts[1].Trim();
                    break;
                default:
                    throw new Exception("Invalid field definition: " + Fields[i] + "'.");
            }
            if (Field.FieldAlias==null) 
                Field.FieldAlias = Field.FieldName;
            m_FieldInfo.Add (Field);
        }
    }
    					

Método CreateJoinTable

Esta sección contiene el código para el método CreateJoinTable .

El siguiente es la convención de llamada para el método CreateJoinTable :
dt = dsHelper.CreateJoinTable("TestTable", ds.Tables["Employees"],
    "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department");
				
este ejemplo de llamada, crea una nueva DataTable con un TableName de TestTable y tres campos (FName, LName y departamento). Estos tres campos tienen el mismo tipo como el nombre y los campos de apellidos de la tabla Employees y el campo DepartmentName en la tabla primaria que se tiene acceso a través del objeto DepartmentEmployee DataRelation de datos.

Utilice la siguiente sintaxis para especificar campos en la lista de campos:
[relationname.]fieldname[ alias], ...
				
Nota siguiente para esta sintaxis:
  • ColumnName y las propiedades DataType son las propiedades sólo a las que se copian al destino DataTable .
  • El resultado se copia para campos que contienen una expresión.
  • Puede cambiar el nombre un campo en el destino DataTable especificando un nombre de alias.
  • La lista de campos puede contener un subconjunto de nombres de campos que aparecen en un orden diferente que el orden en el origen de DataTable . Si la lista de campos está en blanco, se produce una excepción.
  • La DataRelation debe están relacionados con las tablas primarias. Por ejemplo, si desea crear una tabla que combina los campos de los clientes, los empleados y las tablas pedidos, debe utilizar la tabla pedidos como la tabla de origen y, a continuación, referencia a campos de los clientes y las tablas empleados por medio de relaciones.
Para llamar al método CreateJoinTable , agregue el método siguiente a la clase DataSetHelper que creó en la sección "":
public DataTable CreateJoinTable(string TableName, DataTable SourceTable, string FieldList)
{
    /*
     * Creates a table based on fields of another table and related parent tables
     * 
     * FieldList syntax: [relationname.]fieldname[ alias][,[relationname.]fieldname[ alias]]...
    */ 
    if (FieldList==null)
    {
        throw new ArgumentException("You must specify at least one field in the field list.");
        //return CreateTable(TableName, SourceTable);
    }
    else
    {
        DataTable dt = new DataTable(TableName);
        ParseFieldList(FieldList, true);
        foreach(FieldInfo Field in m_FieldInfo)
        {
            if(Field.RelationName==null)
            {
                DataColumn dc = SourceTable.Columns[Field.FieldName];
                dt.Columns.Add(dc.ColumnName, dc.DataType, dc.Expression);
            }
            else
            {
                DataColumn dc = SourceTable.ParentRelations[Field.RelationName].ParentTable.Columns[Field.FieldName];
                dt.Columns.Add(dc.ColumnName, dc.DataType, dc.Expression);
            }
        }
        if (ds!=null)
            ds.Tables.Add(dt);
        return dt;
    }
}
				

Método InsertJoinInto

Esta sección contiene código para el método InsertJoinInto . El método InsertJoinInto copia los registros que se ordenan y filtran de la tabla de origen y relacionados con tablas de la tabla de destino. Al llamar a la propiedad ParseFieldList , puede analizar las listas que se han analizado anteriormente, si estas listas están disponibles. Si la lista de campos está en blanco, se produce una excepción.

El siguiente es la convención de llamada para el método InsertJoinInto :
dsHelper.InsertJoinInto(ds.Tables["TestTable"], ds.Tables["Employees"], 
    "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department", 
    "EmployeeID<5", "BirthDate");
				
el ejemplo de llamada copia registros de la DataTable de empleados (y el campo DepartmentName de una DataTable relacionada) a la DataTable de TestTable, que se filtra en "EmployeeID < 5" y está ordenada por fecha de nacimiento.

Nota : el filtro y las expresiones de ordenación se aplican sólo a la tabla de origen y no a las tablas relacionadas.

Para llamar al método InsertJoinInto , agregue el método siguiente a la clase DataSetHelper que creó en la sección "":
public void InsertJoinInto(DataTable DestTable, DataTable SourceTable, 
    string FieldList, string RowFilter, string Sort)
{
    /*
    * Copies the selected rows and columns from SourceTable and inserts them into DestTable
    * FieldList has same format as CreatejoinTable
    */ 
    if (FieldList==null)
    {
        throw new ArgumentException("You must specify at least one field in the field list.");
        //InsertInto(DestTable, SourceTable, RowFilter, Sort);
    }
    else
    {
    ParseFieldList(FieldList, true);
    DataRow[] Rows = SourceTable.Select(RowFilter, Sort);
    foreach(DataRow SourceRow in Rows)
    {
            DataRow DestRow = DestTable.NewRow();
            foreach(FieldInfo Field in m_FieldInfo)
            {
                if(Field.RelationName==null)
                {
                    DestRow[Field.FieldName] = SourceRow[Field.FieldName];
                }
                else
                {
                    DataRow ParentRow = SourceRow.GetParentRow(Field.RelationName);
                    DestRow[Field.FieldName] = ParentRow[Field.FieldName];
                }
            }
            DestTable.Rows.Add(DestRow);
        }
    }
}
				

Método SelectJoinInto

Esta sección contiene el código para el método SelectJoinInto . Este método es una combinación de la CreateJoinTable y los métodos InsertJoinInto . El método SelectJoinInto crea una nueva DataTable según DataTable objetos y copia registros existentes que están ordenados y filtrados en la nueva DataTable .

El siguiente es la convención de llamada para el método SelectJoinInto :
dt = dsHelper.SelectInto("TestTable", ds.Tables["Employees"], 
    "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department", "EmployeeID<5", "BirthDate");
				
llamada ejemplo crea un DataTable denominado TestTable con tres campos. Estos tres campos se basan en el nombre y los campos LastName de la DataTable de empleados y el campo DepartmentName de la DataTable que se hace referencia a través de la DepartmentEmployee DataRelation . A continuación, en este ejemplo copia los registros de la DataTable de empleados a TestTable DataTable , que se filtra en "EmployeeID < 5" y está ordenada por fecha de nacimiento.

Nota : el filtro y las expresiones de ordenación se aplican sólo a la tabla de origen y no a las tablas relacionadas.

Para llamar al método SelectJoinInto , agregue el método siguiente a la clase DataSetHelper que creó en la sección "":
public DataTable SelectJoinInto(string TableName, DataTable SourceTable, string FieldList, string RowFilter, string Sort)
{
    /*
     * Selects sorted, filtered values from one DataTable to another.
     * Allows you to specify relationname.fieldname in the FieldList to include fields from
     *  a parent table. The Sort and Filter only apply to the base table and not to related tables.
    */ 
    DataTable dt = CreateJoinTable(TableName, SourceTable, FieldList);
    InsertJoinInto(dt, SourceTable, FieldList, RowFilter, Sort);
    return dt;
}
				

Probar la aplicación

  1. Guarde y, a continuación, compile la clase DataSetHelper que creó en las secciones anteriores.
  2. Siga estos pasos para crear una nueva aplicación de Windows de Visual C#:
    1. Inicie Visual Studio NET..
    2. En el menú archivo , seleccione nuevo y, a continuación, haga clic en proyecto .
    3. En el cuadro de diálogo Nuevo proyecto , haga clic en Proyectos de Visual C# en Tipos de proyecto y, después, haga clic en Aplicación para Windows en plantillas .
  3. En el Explorador de soluciones, haga clic con el botón secundario en la solución y, a continuación, haga clic en Agregar proyecto existente . Agregue el proyecto DataSetHelper.
  4. En el menú proyecto , haga clic en Agregar referencia .
  5. En el cuadro de diálogo Agregar referencia , haga clic en la ficha proyectos y, a continuación, agregue una referencia al proyecto DataSetHelper a la aplicación Windows Forms.
  6. En el Diseñador de formulario, arrastre tres controles Button y un control DataGrid desde el cuadro de herramientas al formulario. Nombres de los botones btnCreateJoin , btnInsertJoinInto y btnSelectJoinInto . Mantenga el nombre predeterminado para el control DataGrid (dataGrid1).
  7. En el código de formulario, agregue la siguiente instrucción Using al principio de la ventana código:
    using System.Data;
    					
  8. Agregue las siguientes declaraciones de variables a la definición del formulario:
    DataSet ds; DataSetHelper.DataSetHelper dsHelper;
    					
  9. Agregue el código siguiente al evento Form_Load :
    ds = new DataSet();
    dsHelper = new DataSetHelper.DataSetHelper(ref ds);
    //Create source tables
    DataTable dt = new DataTable("Employees");
    dt.Columns.Add("EmployeeID",Type.GetType("System.Int32") );
    dt.Columns.Add("FirstName", Type.GetType("System.String"));
    dt.Columns.Add("LastName", Type.GetType("System.String"));
    dt.Columns.Add("BirthDate", Type.GetType("System.DateTime"));
    dt.Columns.Add("JobTitle", Type.GetType("System.String"));
    dt.Columns.Add("DepartmentID", Type.GetType("System.Int32"));
    dt.Rows.Add(new object[] {1, "Tommy", "Hill", new DateTime(1970, 12, 31),  "Manager", 42});
    dt.Rows.Add(new object[] {2, "Brooke", "Sheals", new DateTime(1977, 12, 31), "Manager", 23});
    dt.Rows.Add(new object[] {3, "Bill", "Blast", new DateTime(1982, 5, 6), "Sales Clerk", 42});
    dt.Rows.Add(new object[] {1, "Kevin", "Kline", new DateTime(1978, 5, 13), "Sales Clerk", 42});
    dt.Rows.Add(new object[] {1, "Martha", "Seward", new DateTime(1976, 7, 4), "Sales Clerk", 23});
    dt.Rows.Add(new object[] {1, "Dora", "Smith", new DateTime(1985, 10, 22), "Trainee", 42});
    dt.Rows.Add(new object[] {1, "Elvis", "Pressman", new DateTime(1972, 11, 5), "Manager", 15});
    dt.Rows.Add(new object[] {1, "Johnny", "Cache", new DateTime(1984, 1, 23), "Sales Clerk", 15});
    dt.Rows.Add(new object[] {1, "Jean", "Hill", new DateTime(1979, 4, 14), "Sales Clerk", 42});
    dt.Rows.Add(new object[] {1, "Anna", "Smith", new DateTime(1985, 6, 26), "Trainee", 15});
    ds.Tables.Add(dt);
    
    dt = new DataTable("Departments");
    dt.Columns.Add("DepartmentID", Type.GetType("System.Int32"));
    dt.Columns.Add("DepartmentName", Type.GetType("System.String"));
    dt.Rows.Add(new object[] {15, "Men's Clothing"});
    dt.Rows.Add(new object[] {23, "Women's Clothing"});
    dt.Rows.Add(new object[] {42, "Children's Clothing"});
    ds.Tables.Add(dt);
    
    ds.Relations.Add("DepartmentEmployee",     ds.Tables["Departments"].Columns["DepartmentID"], 
        ds.Tables["Employees"].Columns["DepartmentID"]);
    					
  10. Agregue el código siguiente al evento btnCreateJoin_Click :
    dsHelper.CreateJoinTable("EmpDept",ds.Tables["Employees"], 
        "FirstName FName,LastName LName,BirthDate,DepartmentEmployee.DepartmentName Department");
    dataGrid1.SetDataBinding(ds, "EmpDept");
    					
  11. Agregue el código siguiente al evento btnInsertJoinInto_Click :
    dsHelper.InsertJoinInto(ds.Tables["EmpDept"], ds.Tables["Employees"], 
        "FirstName FName,LastName LName,BirthDate,DepartmentEmployee.DepartmentName Department",
        "JobTitle='Sales Clerk'", "DepartmentID");
    dataGrid1.SetDataBinding(ds, "EmpDept");
    					
  12. Agregue el código siguiente al evento btnSelectJoinInto_Click :
    dsHelper.SelectJoinInto("EmpDept2", ds.Tables["Employees"],
        "FirstName,LastName,BirthDate BDate,DepartmentEmployee.DepartmentName Department", 
        "JobTitle='Manager'", "DepartmentID");
    dataGrid1.SetDataBinding(ds, "EmpDept2");
    					
  13. Ejecutar la aplicación y, a continuación, haga clic en cada uno de los botones. Observe que el control DataGrid está relleno con las tablas y los datos desde el código.

    Nota : puede hacer clic sólo en el btnCreateJoin y los botones btnSelectJoinInto una vez. Si hace clic en cualquiera de estos botones más de una vez, recibirá un mensaje de error que intenta agregar la misma tabla two times. Además, debe hacer clic en btnCreateJoin antes de hacer clic en btnInsertJoinInto ; en caso contrario, el destino DataTable no se crea. Si hace clic en el botón btnInsertJoinInto varias veces, llenar el DataGrid con registros duplicados.

Ideas de mejora

  • ColumnName y las propiedades DataType son las propiedades sólo a las que se copian al destino DataTable . Puede extender el método CreateTable para copiar propiedades adicionales, como la propiedad MaxLength , o puede crear nuevas columnas de claves.
  • No se copia la propiedad Expression ; en su lugar, se copia el resultado. Por lo tanto, no es necesario agregar campos que hace referencia la expresión para la tabla de destino. Además, la columna de destino puede aparecer antes en la lista de resultados que cualquiera de las columnas que esta columna depende de lo contrario. Puede modificar el método CreateTable para copiar la expresión (la columna InsertInto omite columnas con una expresión ), aunque esto está sujeta a las limitaciones que se mencionan anteriormente en este párrafo.
  • Puede combinar la funcionalidad de la CreateJoinTable , el InsertJoinInto y los métodos SelectJoinInto en el CreateTable , el InsertInto y los métodos SelectInto . Para obtener información adicional acerca de la CreateTable , el InsertInto y los métodos SelectInto , haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
    326009Cómo: Implementar una clase auxiliar DataSet SELECT INTO en Visual C# .NET
    Si no desea combinar estos métodos pero si tiene dos conjuntos de métodos en una sola clase, puede habilitar la CreateJoinTable y los métodos InsertJoinInto para controlar una lista de campo vacío quitando las instrucciones throw y quitando las llamadas a métodos InsertInto en las siguientes líneas de código y la CreateTable :
        if (FieldList==null)
        {
            throw new ArgumentException("You must specify at least one field in the field list.");
            //return CreateTable(TableName, SourceTable);
        }
    					
    - y -
        if (FieldList==null)
        {
            throw new ArgumentException("You must specify at least one field in the field list.");
            //InsertInto(DestTable, SourceTable, RowFilter, Sort);
        }
    					

Solución de problemas

  • Fieldname y las partes alias de la lista de campos deben cumplir las convenciones de nomenclatura DataColumn . El Analizador restringe también los nombres en que el nombre no debe contener un punto (.), una coma (,) o un espacio ().
  • Si hace clic en un botón de más de una vez, la misma tabla se agrega dos veces al DataSet , que da como resultado una excepción. Para evitar este problema, puede agregar código a la aplicación de prueba para comprobar si ya existe un DataTable con el mismo nombre. Como alternativa, puede crear la clase DataSetHelper sin una referencia a un DataSet y a continuación, enlazar la propiedad DataGrid.DataSource directamente a la variable dt en lugar de mediante la llamada de método SetDataBinding .
  • Si la tabla de origen utiliza tipos de datos personalizado (es decir, una clase), debe agregar código al método InsertJoinInto para realizar una copia profunda de los datos. En caso contrario, se copia sólo una referencia.

Propiedades

Id. de artículo: 326080 - Última revisión: miércoles, 03 de septiembre de 2003 - Versión: 2.3
La información de este artículo se refiere a:
  • Microsoft ADO.NET 1.1
  • Microsoft ADO.NET 1.0
  • Microsoft Visual C# .NET 2003 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
Palabras clave: 
kbmt kbhowtomaster kbsystemdata KB326080 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 326080

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com