COMO: Implementar uma classe de programa auxiliar DataSet JOIN no Visual C# .NET

Traduções de Artigos Traduções de Artigos
Artigo: 326080 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

Este artigo passo a passo descreve como implementar e utilizar como uma classe DataSetHelper que inclui código de exemplo para criar um objecto de DataTable a partir de duas ou mais definições DataTable relacionadas e copia os registos que são ordenados e filtrados os objectos de DataTable de origem para o destino DataTable .

Para efectuar este procedimento, pode utilizar os seguintes métodos públicos:
  • CreateJoinTable
  • InsertJoinInto
  • SelectJoinInto
Chama o método SelectJoinInto CreateJoinTable e os métodos InsertJoinInto . Também pode utilizar um método e dados membros privada do programa auxiliar para armazenar a lista de campos analisados.

A classe DataSetHelper inclui uma variável de membro DataSet . Opcionalmente, pode atribuir um DataSet existente à variável de membro DataSet . Se a variável de membro apontar para um DataSet válido, quaisquer objectos de DataTable CreateJoinTable ou o método SelectJoinInto cria são adicionados ao DataSet . Em qualquer dos casos, a chamada de método devolve uma referência ao objecto de DataTable . O método InsertJoinInto requer um destino existente DataTable e não devolve nada.

Para mais informações sobre objectos de DataSet , clique no número de artigo existente abaixo para visualizar o artigo na base de dados de conhecimento da Microsoft:
313485INFO: Guia para DataSet ADO.NET, DataView e DataViewManager

Requisitos

A lista seguinte descreve o hardware recomendado, software, infra-estrutura de rede e service packs são necessários:
  • Microsoft Windows XP, Windows 2000 ou Windows NT 4.0 Service Pack 6a
  • Microsoft Visual Studio .NET
Este artigo pressupõe que está familiarizado com os seguintes tópicos:
  • O Visual C# .NET sintaxe
  • Noções básicas do ADO.NET e sintaxe

Classe DataSetHelper da shell

O código nesta secção declara a classe de shell à qual todos os artigos DataSetHelper adicionar métodos e variáveis de membros.
  1. Inicie o Visual Studio NET..
  2. No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
  3. Na caixa de diálogo Novo projecto , clique em Visual C# Projects em Project Types e, em seguida, clique em Biblioteca de classes em modelos .
  4. Na caixa nome , escreva DataSetHelper .
  5. Substituir o código de classe o seguinte código:
    public class DataSetHelper
    {
        public DataSet ds;
    
        public DataSetHelper(ref DataSet DataSet)
        {
    	ds = DataSet;
        }
        public DataSetHelper()
        {
    	ds = null;
        }
    }
    					
    pode utilizar as duas sobrecargas para o construtor para criar uma instância da classe com ou sem uma referência a um DataSet válido. Para uma classe que contém uma referência a um DataSet válido, os objectos de DataTable que devolvem os métodos são também adicionados automaticamente a DataSet .

Analisador de lista de campos

Esta secção contém o código para um analisador de lista de campo. A estrutura analisada é utilizada para que CreateJoinTable e os métodos InsertJoinInto não têm a lista de campos de nova análise. Estes métodos tem de reanálise a lista de campos se estes são chamados a partir do método SelectJoinInto ou do seu próprio código. A lista de campos analisados e lista de campos não analisados são armazenadas em privado variáveis de membros da classe DataSetHelper .
  1. Suplemento seguinte definição de classe privada a classe DataSetHelper que criou na secção "":
    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 classe é comum a outros artigos DataSetHelper e contém alguns campos que não utilize este artigo.

  2. Adicionar as seguintes variáveis membro privado a definição de classe imediatamente após a declaração de DataSet :
    private System.Collections.ArrayList m_FieldInfo; private string m_FieldList; 
    					
  3. Adicione o seguinte método privada à definição de classe. Este método é o mesmo método que é utilizado nos outros artigos 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 secção contém o código para o método CreateJoinTable .

Segue-se a convenção de chamada para o método CreateJoinTable :
dt = dsHelper.CreateJoinTable("TestTable", ds.Tables["Employees"],
    "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department");
				
este exemplo chamada cria uma nova DataTable com um TableName TestTable e três campos (Nm lnome e departamento). Estes três campos têm o mesmo tipo como o nome e os campos Apelido na tabela Empregados e o campo DepartmentName da tabela principal que é acedido através do objecto DepartmentEmployee DataRelation de dados.

Utilize a seguinte sintaxe para especificar campos na lista de campos:
[relationname.]fieldname[ alias], ...
				
Note o seguinte para esta sintaxe:
  • ColumnName e as propriedades de tipo de dados são apenas propriedades que são copiadas para o destino DataTable .
  • O resultado avaliado é copiado para campos que contêm uma expressão.
  • Pode mudar o nome um campo de destino DataTable especificando um nome de alias.
  • A lista de campos pode conter um subconjunto dos nomes dos campos listados na ordem diferente a ordem na origem de DataTable . Se a lista de campos estiver em branco, é emitida uma excepção.
  • DataRelation tem dizem respeito a tabelas principais. Por exemplo, se pretender criar uma tabela que combina campos de clientes, os empregados e as tabelas Encomendas, deve utilizam a tabela Encomendas como a tabela de origem e, em seguida, fazer referência a campos de clientes e as tabelas empregados através de relações.
Para chamar o método CreateJoinTable , adicione o seguinte método à classe DataSetHelper que criou na secção "":
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 secção contém código para o método InsertJoinInto . O método InsertJoinInto copia os registos que são ordenados e filtrados da tabela de origem e tabelas relacionadas para a tabela de destino. Quando contactar a propriedade ParseFieldList , pode analisar listas que anteriormente foram analisadas, se estas listas estiverem disponíveis. Se a lista de campos estiver em branco, é emitida uma excepção.

Segue-se a convenção de chamada para o método InsertJoinInto :
dsHelper.InsertJoinInto(ds.Tables["TestTable"], ds.Tables["Employees"], 
    "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department", 
    "EmployeeID<5", "BirthDate");
				
o exemplo de chamada copia registos de empregados DataTable (e campo de uma DataTable relacionados DepartmentName) a TestTable DataTable , que é filtrado no "CódigoDoEmpregado < 5" e ordenadas pela data de nascimento.

Nota : O filtro e ordenação expressões aplicam-se apenas a tabela de origem e não a todas as tabelas relacionadas.

Para chamar o método InsertJoinInto , adicione o seguinte método à classe DataSetHelper que criou na secção "":
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 secção contém o código para o método SelectJoinInto . Este método é uma combinação de CreateJoinTable e os métodos InsertJoinInto . O método SelectJoinInto cria uma nova DataTable com base no DataTable objectos e copia registos existentes que são ordenados e filtrados para o novo DataTable .

Segue-se a convenção de chamada para o método SelectJoinInto :
dt = dsHelper.SelectInto("TestTable", ds.Tables["Employees"], 
    "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department", "EmployeeID<5", "BirthDate");
				
chamada este exemplo cria um DataTable com o nome TestTable com três campos. Estes três campos baseiam-se o nome e campos de empregados DataTable Apelido e o campo DepartmentName do DataTable referenciado através de DepartmentEmployee DataRelation . Em seguida, este exemplo copia registos de empregados DataTable para TestTable DataTable , que é filtrado no "CódigoDoEmpregado < 5" e ordenadas pela data de nascimento.

Nota : O filtro e ordenação expressões aplicam-se apenas a tabela de origem e não a tabelas relacionadas.

Para chamar o método SelectJoinInto , adicione o seguinte método à classe DataSetHelper que criou na secção "":
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;
}
				

Testar a aplicação

  1. Guarde e, em seguida, compilar a classe DataSetHelper que criou no secções anteriores.
  2. Siga estes passos para criar uma nova aplicação do Visual C# Windows:
    1. Inicie o Visual Studio NET..
    2. No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
    3. Na caixa de diálogo Novo projecto , clique em Visual C# Projects em Project Types e, em seguida, clique em Aplicação do Windows em modelos .
  3. No Solution Explorer, clique com o botão direito do rato a solução e, em seguida, clique em Adicionar projecto existente . Adicione o projecto DataSetHelper.
  4. No menu projecto , clique em Add Reference .
  5. Na caixa de diálogo Adicionar referência do , clique no separador projectos e, em seguida, adicionar uma referência ao projecto DataSetHelper à aplicação de formulários do Windows.
  6. No estruturador de formulário, arraste três controlos do botão e o controlo DataGrid da caixa de ferramentas para o formulário. Nomes de botões btnCreateJoin , btnInsertJoinInto e btnSelectJoinInto . Mantenha o nome predefinido para o controlo DataGrid (dataGrid1).
  7. No código de formulário, adicione a seguinte instrução utilizar na parte superior da janela Code:
    using System.Data;
    					
  8. Adicionar as declarações de variáveis seguintes a definição do formulário:
    DataSet ds; DataSetHelper.DataSetHelper dsHelper;
    					
  9. Adicione o seguinte código ao 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. Adicione o seguinte código ao evento btnCreateJoin_Click :
    dsHelper.CreateJoinTable("EmpDept",ds.Tables["Employees"], 
        "FirstName FName,LastName LName,BirthDate,DepartmentEmployee.DepartmentName Department");
    dataGrid1.SetDataBinding(ds, "EmpDept");
    					
  11. Adicione o seguinte código ao 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. Adicione o seguinte código ao evento btnSelectJoinInto_Click :
    dsHelper.SelectJoinInto("EmpDept2", ds.Tables["Employees"],
        "FirstName,LastName,BirthDate BDate,DepartmentEmployee.DepartmentName Department", 
        "JobTitle='Manager'", "DepartmentID");
    dataGrid1.SetDataBinding(ds, "EmpDept2");
    					
  13. Executar a aplicação e clique em cada um dos botões. Repare que a DataGrid é povoado com as tabelas e os dados contra o código.

    Nota : pode apenas clicar btnCreateJoin e os botões btnSelectJoinInto uma vez. Se clicar em destes botões mais do que uma vez, receberá uma mensagem de erro que está a tentar adicionar a mesma tabela duas vezes. Além disso, tem de clicar em btnCreateJoin antes de clicar em btnInsertJoinInto ; caso contrário, o destino DataTable não é criada. Se clicar no botão btnInsertJoinInto várias vezes, preencha a DataGrid com registos duplicados.

Ideias de melhoramento

  • ColumnName e as propriedades de tipo de dados são apenas propriedades que são copiadas para o destino DataTable . Pode expandir o método CreateTable para copiar propriedades adicionais, tais como a propriedade MaxLength , ou pode criar novas colunas chaves.
  • A propriedade Expression não é copiada; em vez disso, o resultado avaliado é copiado. Por conseguinte, não é necessário adicionar campos referenciados pela expressão para a tabela de destino. Além disso, a coluna de destino pode aparecer anterior na lista de resultados de qualquer uma das colunas que esta coluna depende caso contrário. Pode modificar o método CreateTable para copiar a expressão (a coluna InsertInto ignora as colunas com uma expressão ), apesar de esta ser sujeitos às limitações mencionadas anteriormente neste parágrafo.
  • É possível intercalar a funcionalidade de CreateJoinTable InsertJoinInto e os métodos SelectJoinInto em CreateTable , InsertInto e os métodos SelectInto . Para obter informações adicionais sobre CreateTable , InsertInto e os métodos SelectInto , clique no número de artigo existente abaixo para visualizar o artigo na base de dados de conhecimento da Microsoft:
    326009COMO: Implementar uma classe de programa auxiliar DataSet SELECT INTO no Visual C# .NET
    Se não pretender intercalar estes métodos, mas se tiver ambos os conjuntos de métodos de uma única classe, é possível activar CreateJoinTable e os métodos InsertJoinInto processar uma lista de campo vazio, removendo as instruções ' Throw e por uncommenting as chamadas para CreateTable e os métodos InsertInto as seguintes linhas de código:
        if (FieldList==null)
        {
            throw new ArgumentException("You must specify at least one field in the field list.");
            //return CreateTable(TableName, SourceTable);
        }
    					
    - e -
        if (FieldList==null)
        {
            throw new ArgumentException("You must specify at least one field in the field list.");
            //InsertInto(DestTable, SourceTable, RowFilter, Sort);
        }
    					

Resolução de problemas

  • O NomeDoCampo e as partes alias da lista de campos tem em conformidade com as convenções de nomenclatura DataColumn . O analisador também limita os nomes, que o nome não tem de conter um ponto final (.), uma vírgula (,) ou um espaço ().
  • Se clicar num botão mais do que uma vez, a mesma tabela é adicionada duas vezes para DataSet , que resulta numa excepção. Para contornar este problema, pode adicionar código à aplicação de teste para verificar se uma DataTable com o mesmo nome já existe. Em alternativa, pode criar a classe DataSetHelper sem uma referência a um DataSet e, em seguida, ligue a propriedade DataGrid.DataSource directamente para a variável dt em vez de usando a chamada de método SetDataBinding .
  • Se a tabela de origem utiliza tipos de dados personalizados (ou seja, uma classe), tem de adicionar código para o método InsertJoinInto para efectuar uma cópia profundidade dos dados. Caso contrário, apenas uma referência é copiada.

Propriedades

Artigo: 326080 - Última revisão: 3 de setembro de 2003 - Revisão: 2.3
A informação contida neste artigo aplica-se 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
Palavras-chave: 
kbmt kbhowtomaster kbsystemdata KB326080 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 326080

Submeter comentários

 

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