none
Dataset - Löschen von Zeilen - Möglichkeiten RRS feed

  • Frage

  •  
    
    

    Hallo,

    welche Möglichkeiten bieten sich an, in einem Dataset gezielt eine Zeile zu löschen, ohne den Primärschlüssel zu kennen.

    LinQ scheidet ja bei Dataset aus.

    oder doch besser über SQL Query?

    Ich habe eine Materialwirtschaft, in dem ich eine ID, nicht den Primärschlüssel löschen muss.

    tblProduct.FindByProductRef  habe ich ja nicht.

    Danke für Tipps.

     

     public partial class DataSetMaterialSettings
      {
        public bool DeleteEntry(string matID)
        {
          bool ret = false;
          System.Data.DataView dvMaterialSettings = tblMaterial.DefaultView;
    
          foreach (System.Data.DataRowView drv in dvMaterialSettings)
          {
            tblMaterialRow tblMRow = (tblMaterialRow)drv.Row;
            if (tblMRow.MatID == matID)
            {
              drv.Delete();
              break;
            }
          }
          return ret;
        }
      }

     

    Grüße Andreas


    • Bearbeitet Andreas Bauer2 Donnerstag, 28. Juli 2011 09:39 Formatierung
    Donnerstag, 28. Juli 2011 09:37

Antworten

  • Hallo Andreas,

    Bei "Materialwirtschaft" schalte ich automatisch auf "Datenbank". Ist angeboren. 
    Wenn Du nun aber nur mit lokalen DataSets arbeitest, machen SqlDataAdapter & Co. freilich wenig Sinn.

    Ich würde das Löschen so handhaben:

    namespace ConsoleApplication1 {
      using System.Linq;
      
      public partial class DataSetMaterialSettings {
        partial class MaterialDataTable {
          public void DeleteEntry(string matID) {
            var rows = (from r in this.AsEnumerable()
                  where r.MatID == matID
                  select r).ToArray();
    
            foreach (var row in rows)
              row.Delete();
          }
        }
      }
    }
    

    In der Hauptanwendung hast Du dann eben etwas wie:

    // Tabelle definieren
    DataSetMaterialSettings.MaterialDataTable table = new DataSetMaterialSettings.MaterialDataTable();
    
    // Daten hinzufügen
    table.AddMaterialRow(1, "ID1", "Material_1");
    table.AddMaterialRow(2, "ID2", "Material_2");
    table.AddMaterialRow(3, "ID3", "Material_3");
    
    // Datenzeile löschen
    table.DeleteEntry("ID2");
    
    


    Gruß
    Marcel

    Donnerstag, 28. Juli 2011 12:13
    Moderator
  • Hallo Andreas,

    SQL ohne Datenbankserver, das ist begrenzt möglich: Du könntest z.B. die Tabelle anhand des Löschkriteriums in SQL-Manier filtern (der Select-Ausdruck entspricht dabei in etwa dem WHERE-Teil eines SQL-Abfrage):

    DataRow[] rowsToDelete = table.Select("MatID = 'ID3'");
    Array.ForEach(rowsToDelete, r => r.Delete());
    

    DataTable.Select-Methode (String):
    http://msdn.microsoft.com/de-de/library/det4aw50.aspx

    (Ähnlich verhält es sich mit DataView.RowFilter)

    Aber wieso möchtest Du SQL-Ausdrücke auf verbindungslose DataSets anwenden, wenn Du mit LINQ to Dataset bereits ein sehr cleveres und mächtiges Tool in der Hand hast?

    LINQ to DataSet:
    http://msdn.microsoft.com/de-de/library/bb386977.aspx

    [Es gibt einige wenige esoterische Anwendungsgebiete, wo man Daten an einen Datenbankserver sendet, wo dann temporäre Tabellen erstellt werden und anschließend über direktes SQL oder gesp. Prozeduren komplexe Verarbeitungsaufgaben durchgeführt werden, aber ich glaube nicht, dass dich das hier und jetzt interessiert.]

    Gruß
    Marcel

    Donnerstag, 28. Juli 2011 16:57
    Moderator

Alle Antworten

  • Hallo Andreas,

    Für client-seitige Verarbeitung kannst Du sehr wohl LINQ benutzen.
    Hier ein kleines Beispiel:

    using System;
    using System.Linq;
    using System.Data;
    
    namespace ConsoleApplication1 {
      class Program {
        static void Main(string[] args) {
          // Tabelle definieren
          DataSet dataSet = new DataSet();
          DataColumn[] columns = new DataColumn[] { 
            new DataColumn("PK", typeof(long)) { AutoIncrement = true, AutoIncrementStep=1 }, 
            new DataColumn("ID") { AllowDBNull = false }, 
            new DataColumn("Artikelbezeichnung")
          };
    
          DataTable table = new DataTable();
          table.Columns.AddRange(columns);
          table.PrimaryKey = new DataColumn[] { columns[0]};
    
          dataSet.Tables.Add(table);
    
          // Daten hinzufügen
          table.Rows.Add(new object[] { 1, "ID1", "Artikel_1" });
          table.Rows.Add(new object[] { 2, "ID2", "Artikel_2" });
          table.Rows.Add(new object[] { 3, "ID3", "Artikel_3" });
          PrintRowsCount(table);
    
          // Suchen
          var rows = (from row in table.AsEnumerable()
                where row.Field<string>("ID") == "ID2"
                select row).ToArray();
    
          // Löschen
          foreach (var row in rows) {
            Console.WriteLine("Lösche Datenzeile mit ID {0}", row["ID"]);
            row.Delete();
          }
    
          PrintRowsCount(table);
          Console.ReadKey(true);
        }
    
        private static void PrintRowsCount(DataTable table) {
          Console.WriteLine("Tabelle enthält {0} Datenzeilen.", table.Rows.Count);
        }
      }
    }
    

    Weiterhin hast Du die Möglichkeit über SqlDataAdapter.DeleteCommand + SqlDataAdapter.Update, SqlCommand.ExecuteNonQuery (mit CommandType Text/StoredProcedure) oder dem TableAdapter (bzw. benutzerdefinierten Abfragen) Zeilen zu filtern und zu löschen, usw., usf.

    Startseite der ADO.NET-Dokumentation:
    http://msdn.microsoft.com/de-de/library/e80y5yhx.aspx

    Gruß
    Marcel

    Donnerstag, 28. Juli 2011 11:23
    Moderator
  • CommandType Text/StoredProcedure) oder dem TableAdapter (bzw. benutzerdefinierten Abfragen) Zeilen zu filtern und zu löschen, usw., usf.

    Startseite der ADO.NET-Dokumentation:
    http://msdn.microsoft.com/de-de/library/e80y5yhx.aspx

     

    Hallo Marcel,

    jaja, aber kannst Du mir konkret ein Beispiel nennen ohne Datenbank im Hintergrund, sprich nur Dataset.

    http://msdn.microsoft.com/de-de/library/system.data.sqlclient.sqldataadapter.deletecommand(v=VS.90).aspx

    Ich speichere die Daten eben als XML Datei. Benötige keine MDB etc. Datei.

    Herzlichen Dank im Voraus!

    Das wusste ich  nicht. DANKE.

     // Suchen
          var rows = (from row in table.AsEnumerable()
                where row.Field<string>("ID") == "ID2"
                select row).ToArray();

          // Löschen
          foreach (var row in rows) { Console.WriteLine("Lösche Datenzeile mit ID {0}", row["ID"]);
            row.Delete();
          }

    Grüße Andreas

    Donnerstag, 28. Juli 2011 11:45
  • Hallo Andreas,

    Bei "Materialwirtschaft" schalte ich automatisch auf "Datenbank". Ist angeboren. 
    Wenn Du nun aber nur mit lokalen DataSets arbeitest, machen SqlDataAdapter & Co. freilich wenig Sinn.

    Ich würde das Löschen so handhaben:

    namespace ConsoleApplication1 {
      using System.Linq;
      
      public partial class DataSetMaterialSettings {
        partial class MaterialDataTable {
          public void DeleteEntry(string matID) {
            var rows = (from r in this.AsEnumerable()
                  where r.MatID == matID
                  select r).ToArray();
    
            foreach (var row in rows)
              row.Delete();
          }
        }
      }
    }
    

    In der Hauptanwendung hast Du dann eben etwas wie:

    // Tabelle definieren
    DataSetMaterialSettings.MaterialDataTable table = new DataSetMaterialSettings.MaterialDataTable();
    
    // Daten hinzufügen
    table.AddMaterialRow(1, "ID1", "Material_1");
    table.AddMaterialRow(2, "ID2", "Material_2");
    table.AddMaterialRow(3, "ID3", "Material_3");
    
    // Datenzeile löschen
    table.DeleteEntry("ID2");
    
    


    Gruß
    Marcel

    Donnerstag, 28. Juli 2011 12:13
    Moderator
  • Hallo Andreas,

    Bei "Materialwirtschaft" schalte ich automatisch auf "Datenbank". Ist angeboren. 
    Wenn Du nun aber nur mit lokalen DataSets arbeitest, machen SqlDataAdapter & Co. freilich wenig Sinn.

    Ich würde das Löschen so handhaben:

    Hallo Marcel,

    Danke und passt.

    Abschließend, damit ich die Möglichkeiten sehe.

    Wenn ich nur ein Dataset habe, kann ich definitiv keine SQL Query starten, erzeugen?

    Gruß, Andreas

    Donnerstag, 28. Juli 2011 14:50
  • Hallo Andreas,

    SQL ohne Datenbankserver, das ist begrenzt möglich: Du könntest z.B. die Tabelle anhand des Löschkriteriums in SQL-Manier filtern (der Select-Ausdruck entspricht dabei in etwa dem WHERE-Teil eines SQL-Abfrage):

    DataRow[] rowsToDelete = table.Select("MatID = 'ID3'");
    Array.ForEach(rowsToDelete, r => r.Delete());
    

    DataTable.Select-Methode (String):
    http://msdn.microsoft.com/de-de/library/det4aw50.aspx

    (Ähnlich verhält es sich mit DataView.RowFilter)

    Aber wieso möchtest Du SQL-Ausdrücke auf verbindungslose DataSets anwenden, wenn Du mit LINQ to Dataset bereits ein sehr cleveres und mächtiges Tool in der Hand hast?

    LINQ to DataSet:
    http://msdn.microsoft.com/de-de/library/bb386977.aspx

    [Es gibt einige wenige esoterische Anwendungsgebiete, wo man Daten an einen Datenbankserver sendet, wo dann temporäre Tabellen erstellt werden und anschließend über direktes SQL oder gesp. Prozeduren komplexe Verarbeitungsaufgaben durchgeführt werden, aber ich glaube nicht, dass dich das hier und jetzt interessiert.]

    Gruß
    Marcel

    Donnerstag, 28. Juli 2011 16:57
    Moderator
  • DataSets anwenden, wenn Du mit LINQ to Dataset bereits ein sehr cleveres und mächtiges Tool in der Hand hast?

    Hallo Marcel,

    ja ich wollte eben nur die Möglichkeiten wissen.

    Man hat eine Aufgabe.

    Der Eine braucht 1 Minute, weil es das Richtige kennt, der Andere benötigt 1 Tag.

    Ja das muss man wissen.

    http://msdn.microsoft.com/de-de/library/bb386998(v=VS.90).aspx

    IEnumerable<DataRow> query1 = from contact in contactTable.AsEnumerable()
                                  where contact.Field<string>("Title") == "Ms."
                                  select contact;

    Also macht es mehr Sinn, ich frage bei den Profis nach. Danke.

    Grüße Andreas

    Donnerstag, 28. Juli 2011 17:47