none
Dataset XML/Datei - DataGridView - Query/Filterung RRS feed

  • Frage

  • Hallo Zusammen,
    ich suche nach einer einfachen brauchbaren Lösung.
    Folgendes Problem.
    Ich habe ein Dataset mit der Tabelle tblProduct.
    Diese Tabelle beinhaltet mehrere Produkte mit gleichen Breiten.
    Was will ich?
    In einem DataGridView sollen jetzt alle möglichen Breiten genau! einmal!
    abgebildet werden.
    Wie kann ich dieses Ziel erreichen?

    Bild:     http://www1.minpic.de/bild_anzeigen.php?id=130563&key=536461&ende


    Ich komme nicht weiter, Filter geht auch nicht, doch über SQL oder LinQ ?

    Ich könnte vielleicht die Tabelle selbst durchlaufen, die Werte merken,
    eine neue Tabelle erstellen, dieses dem DataGridView zuweisen.
    Geht doch bestimmt einfacher.

    Danke für Tipps im Voraus!

    Grüße Andreas

    Das habe ich geprüft, ohne Erfolg.

      tblProductBindingSource.Filter = "Name LIKE 'T%'"; // Richting ?!?!
      dGVWidth.DataSource = tblProductBindingSource;

    http://openbook.galileocomputing.de/visual_csharp/visual_csharp_28_007.htm#mj6e632ec9e5f1305ce0c1f6ef71160687

     public void LoadDatabase(string sFilename)
        {
            RDatabase.DataSetRDatabase dsProductDB = new RDatabase.DataSetRDatabase();
            if (sFilename != null && sFilename != "")
                dsProductDB.ReadXml(sFilename);

            dsProductDB.AcceptChanges();
            this.dataSetRDatabase = dsProductDB;
            this.bsRDatabase.DataSource = dataSetRDatabase;
            dGVWidth.DataSource = tblProductBindingSource;
        }

    Montag, 22. November 2010 17:33

Antworten

  • Hallo Andreas,

    zum Beispiel mit "Distinct auf true" in der ToTable-Methode:

     private void Form1_Load(object sender, EventArgs e)
     {
      DsDaten daten = new DsDaten(); // getyptes DataSet
      // MitDemoDatenFüllen(daten);
      daten.ReadXml("daten.xml");
      dgv.DataSource = daten.tblProduct.DefaultView.
      ToTable(true, "Width"); 
     }
    
     private void MitDemoDatenFüllen(DsDaten daten)
     {
      DsDaten.tblProductDataTable dt = new DsDaten.tblProductDataTable();
      dt.AddtblProductRow("0435_R1", 190);
      dt.AddtblProductRow("0435_R1", 220);
      dt.AddtblProductRow("0435_R1", 190);
      dt.AddtblProductRow("0435_R1", 300);
      daten.Tables.Add(dt);
      daten.WriteXml("daten.xml");
     }
    

    (natürlich gäbe es auch die Distinct Methode in LINQ).


    ciao Frank
    • Als Antwort markiert Andreas Bauer2 Dienstag, 23. November 2010 19:14
    Montag, 22. November 2010 20:57
  • Hallo Andreas,
    wie würde es da dann aussehen? Einfach zum Vergleich.

    Im verlinkten MSDN Artikel stehen zwei passende (und sehr einfach gehaltene) Beispiele. Wenn es von deiner Seite her Verständnisprobleme damit gibt, wäre es sinnvoll, wenn Du uns sagen könntest, was genau Du daran nicht verstehst, dann kann man effektiver helfen.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    • Als Antwort markiert Andreas Bauer2 Dienstag, 23. November 2010 19:14
    Dienstag, 23. November 2010 07:37
    Moderator
  • Hallo Andreas,

    Wenn ich das alles richtig verstehe, mußt Du einfach nach der Spalte Width gruppieren und den ersten Wert selektieren.

    using System;
    using System.Linq;
    using System.Data;
    
    namespace Test1
    {
      class Program
      {
        static void Main(string[] args)
        {
          DataTable productsTable = new DataTable("Products");
          productsTable.Columns.AddRange(new[]
          { 
            new DataColumn("ProductID"), 
            new DataColumn("Width", typeof(int))
          });
    
          var values = new object[][]
          {
            new object[] { "0435_R1", 190 },
            new object[] { "0435_R2", 220 },
            new object[] { "Test 3", 190 },
            new object[] { "Test 4", 300 }
          };
          
    
          for (int idx = 0; idx < values.Length; idx++)
            productsTable.Rows.Add(values[idx][0], values[idx][1]);
    
          var query = from r in productsTable.AsEnumerable()
                group r by r.Field<int>("Width") into g1
                select g1.FirstOrDefault();
    
          foreach (var r in query)
          {
            Console.WriteLine("{0}\t{1}",r["ProductID"], r["Width"]);
          }
    
          Console.ReadLine();
        }
      }
    }
    
    

    Ich habe für das obige Konsolen-Beispiel eine untypisierte Tabelle und LINQ to Dataset verwendet, Du kannst aber natürlich auch eine typisierte Tabelle, bzw. LINQ to XML verwenden. Es kommt nur auf die Gruppierung an.

    Gruß
    Marcel

    • Als Antwort markiert Andreas Bauer2 Dienstag, 23. November 2010 19:14
    Dienstag, 23. November 2010 10:03
    Moderator

Alle Antworten

  • Hallo Andreas,

    zum Beispiel mit "Distinct auf true" in der ToTable-Methode:

     private void Form1_Load(object sender, EventArgs e)
     {
      DsDaten daten = new DsDaten(); // getyptes DataSet
      // MitDemoDatenFüllen(daten);
      daten.ReadXml("daten.xml");
      dgv.DataSource = daten.tblProduct.DefaultView.
      ToTable(true, "Width"); 
     }
    
     private void MitDemoDatenFüllen(DsDaten daten)
     {
      DsDaten.tblProductDataTable dt = new DsDaten.tblProductDataTable();
      dt.AddtblProductRow("0435_R1", 190);
      dt.AddtblProductRow("0435_R1", 220);
      dt.AddtblProductRow("0435_R1", 190);
      dt.AddtblProductRow("0435_R1", 300);
      daten.Tables.Add(dt);
      daten.WriteXml("daten.xml");
     }
    

    (natürlich gäbe es auch die Distinct Methode in LINQ).


    ciao Frank
    • Als Antwort markiert Andreas Bauer2 Dienstag, 23. November 2010 19:14
    Montag, 22. November 2010 20:57
  • (natürlich gäbe es auch die Distinct Methode in LINQ).


    ciao Frank


    Guten morgen Frank,

    wie würde es da dann aussehen? Einfach zum Vergleich. Danke und ein schöner Tag

    Andreas

    Dienstag, 23. November 2010 05:24
  • Hallo Andreas,
    wie würde es da dann aussehen? Einfach zum Vergleich.

    Im verlinkten MSDN Artikel stehen zwei passende (und sehr einfach gehaltene) Beispiele. Wenn es von deiner Seite her Verständnisprobleme damit gibt, wäre es sinnvoll, wenn Du uns sagen könntest, was genau Du daran nicht verstehst, dann kann man effektiver helfen.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    • Als Antwort markiert Andreas Bauer2 Dienstag, 23. November 2010 19:14
    Dienstag, 23. November 2010 07:37
    Moderator
  • Hallo Andreas,

    Deine Frage ist berechtigt und leitet sich nicht direkt aus meinen Links ab.
    Hier ein Beispiel mit Linq (eine Spalte / nur Ansehen):

      var distinctRows = (from row in daten.tblProduct
         select new {Width=row["Width"]}).Distinct();
      dgv.DataSource = distinctRows.ToList();
    

    ciao Frank
    Dienstag, 23. November 2010 09:46
  • Hallo Andreas,

    Wenn ich das alles richtig verstehe, mußt Du einfach nach der Spalte Width gruppieren und den ersten Wert selektieren.

    using System;
    using System.Linq;
    using System.Data;
    
    namespace Test1
    {
      class Program
      {
        static void Main(string[] args)
        {
          DataTable productsTable = new DataTable("Products");
          productsTable.Columns.AddRange(new[]
          { 
            new DataColumn("ProductID"), 
            new DataColumn("Width", typeof(int))
          });
    
          var values = new object[][]
          {
            new object[] { "0435_R1", 190 },
            new object[] { "0435_R2", 220 },
            new object[] { "Test 3", 190 },
            new object[] { "Test 4", 300 }
          };
          
    
          for (int idx = 0; idx < values.Length; idx++)
            productsTable.Rows.Add(values[idx][0], values[idx][1]);
    
          var query = from r in productsTable.AsEnumerable()
                group r by r.Field<int>("Width") into g1
                select g1.FirstOrDefault();
    
          foreach (var r in query)
          {
            Console.WriteLine("{0}\t{1}",r["ProductID"], r["Width"]);
          }
    
          Console.ReadLine();
        }
      }
    }
    
    

    Ich habe für das obige Konsolen-Beispiel eine untypisierte Tabelle und LINQ to Dataset verwendet, Du kannst aber natürlich auch eine typisierte Tabelle, bzw. LINQ to XML verwenden. Es kommt nur auf die Gruppierung an.

    Gruß
    Marcel

    • Als Antwort markiert Andreas Bauer2 Dienstag, 23. November 2010 19:14
    Dienstag, 23. November 2010 10:03
    Moderator
  • http://www1.minpic.de/bild_anzeigen.php?id=130706&key=81135203&ende

    Hallo Frank,
    Danke dass ich nochmals nachfragen dürfte.

    Es passst alles und geht wie es haben möchte. Nur über LinQ?

    select  !?!?
     //  Linq (eine Spalte / nur Ansehen):
            var distinctRows = (from row in dsProductDB.tblProduct select new { Width = row["Width"] }).Distinct();
            dGVWidth.DataSource = distinctRows.ToList();
    Das geht nicht.
    Error 28 Cannot convert lambda expression to type 'string' because it is not a delegate type C:\RTest\ucTypeSelectMask.cs 114 64 RTest

     

    Grüße Andreas

     

     

    Dienstag, 23. November 2010 19:12
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Hallo Marcel,
    ja Danke für Deine Hilfe.

    Es sind/waren ja Aufgaben, die in der Tat, wenn man es weiß einfach zu lösen sind.

    a) Breite -- nur einmal darstellen, wenn mehrfach vorhanden
    b) Die Spalte Count zusammenzählen, summieren

    Bei Aufgabenstellung verweisen auf ein eigenständiges Dataset.

    Grüße Andreas

     

    Dienstag, 23. November 2010 19:13
  • Hallo,

    abschließend noch.

    Ich machs so jetzt.

            RDatabase.DataSetRDatabase dsProductDB = new RDatabase.DataSetRDatabase();

            if (sFilename != null && sFilename != "")

                dsProductDB.ReadXml(sFilename);

     

            //dGVWidth.DataSource = dsProductDB.tblProduct.DefaultView.ToTable(true, "Width");

            dsProductDB.AcceptChanges();

            this.dataSetRDatabase = dsProductDB;

     

            this.bsRDatabase.DataSource = dataSetRDatabase.tblProduct.DefaultView.ToTable(true, "Width");

     

     

    Ja das klappt jetzt. Vielen Dank nochmals.

    Das habe ich leider nicht gewusst. Wüsste auch nicht, wie ich das heraus bekommen hätte können.

    100 Bücher und dann wäre ich auch nicht darauf gekommen, vermutlich.

     

    Jeder darf natürlich antworten, bin über jede Anwort dankbar.

     

    Grüße Andreas

     

     

    P.S. Hätte lang dauern können ohne Euch.

     

    distinct

    Typ: System.Boolean
    Wenn true, enthält die zurückgegebene DataTable Zeilen, die über verschiedene Werte für alle Spalten verfügen. Der Standardwert ist false.

     

    Dienstag, 23. November 2010 19:23
  • Hallo Andreas,

         > Linq ... select  !?!?

    ja, select (mit new). (Du kannst mir ggf. Dein Projekt zuschicken). Ich könnte mir vorstellen, dass Deine Spalte "Width" nicht den Typ int32 (im DataSet) hat, sondern string!! Wandle den in int32, wenn möglich!

    Aber ich sehe, Du hast es jetzt über mein vorgeschlagenes ToTable gemacht.
    Insofern - das ist auch eine gute Lösung :-)


    ciao Frank
    Dienstag, 23. November 2010 19:39

  • ja, select (mit new). (Du kannst mir ggf. Dein Projekt zuschicken). Ich könnte mir vorstellen, dass Deine Spalte "Width" nicht den Typ int32 (im DataSet) hat, sondern string!! Wandle den in int32, wenn möglich!

    Hallo Frank,

    //  Linq (eine Spalte / nur Ansehen):

            var distinctRows = (from row in dsProductDB.tblProduct select new { Width = row["Width"] }).Distinct();

            dGVWidth.DataSource = distinctRows.ToList();

     

            dsProductDB.tblProduct.WidthColumn.DataType

    Der Datentyp ist double.

    Müsste man das nicht irgendwie herausbekommen?

    Der andere Weg geht ja, falls Du noch schnell eine Idee hast, gerne.

     

    Konkrete Fragen.

    • Double muss sein.
    • Gibt es eine Möglichkeit vorn einer ‚fremden’ Assembly den Datentyp heraus zu bekommen?

     http://www1.minpic.de/bild_anzeigen.php?id=130814&key=34487556&ende

    Grüße Andreas

    Donnerstag, 25. November 2010 05:21