Biggle's Blog

Web- und Software Development

by Mario Priebe

foreach oder LINQ

Anhand eines einfachen Beispiels möchte ich darstellen, wie man ein verschachteltes foreach-Statement auch mit LINQ umsetzen kann.

Ich habe ein Autohaus und möchte dem Kunden gerne jedes Auto in meinem Sortiment in jeder Farbe anbieten.

Dazu benötige ich die Klassen Car und CarColor. Ich erstelle mir eine Liste von Autos und eine Liste von Farben.

1
2
List<Car> cars = new List<Car> { new Car { Name = "BMW" }, new Car { Name = "Audi" }, new Car { Name = "Seat" }, };
List<CarColor> colors = new List<CarColor> { new CarColor { Color = "blau" }, new CarColor { Color = "rot" }, new CarColor { Color = "gelb" } };

Nun möchte ich jedes Auto jede Farbe zuweisen.
Mit verschachtelte foreach-Schleifen sähe das so aus:

1
2
3
4
5
6
7
foreach (var car in cars)
{
    foreach (var color in colors)
    {
        Console.WriteLine(String.Format("{0} in {1}", car.Name, color.Color));
    }
}

hässlich oder?
Mit LINQ kann ich dieses wie folgt programmieren:

1
2
List<string> offers = cars.SelectMany(color => colors, (car, color) => (String.Format("{0} in {1}", car.Name, color.Color))).ToList();
offers.ForEach(offer => Console.WriteLine(offer));


Ich finde Zweiteres sieht um einiges lesbarer aus, oder was sagst du?


Viel Spaß beim entwickeln : )


by Mario Priebe

Doppelte Einträge aus einer DataTable entfernen | LinqExtension

Folgende LINQExtension* enternt doppelte Einträge einer DataTable und gibt diese zurück

1
2
3
4
5
6
7
8
9
10
public static DataTable DistinctDataTable(this DataTable table)
{
    var resultTable = table.Clone();
    IEnumerable<DataRow> uniqueElements = table.AsEnumerable().Distinct(DataRowComparer.Default);
    foreach (var row in uniqueElements)
    {
        resultTable.ImportRow(row);
    }
    return resultTable;
}

Verwendung:

DataTable resultTable = mainTable.DistinctDataTable();

Viel Spaß beim entwickeln : )

* = ExtensionMethods implementiert man in einer statischen Klasse.

 

by Mario Priebe

.Net Quicky – Linq2Ef Videorial

In diesem (mein erstes btw) Videorial zeige ich unter 5 Minuten, wie man Customer-Daten aus der BeispielDatenbank Northwind via Entity Framework an eine ComboBox bindet.

Ich empfehle gleich nach dem Start auf HD umzustellen, das schärft die Schriften.

YouTube Preview Image

Viel Spass beim entwickeln : )


by Mario Priebe

Geschwindigkeitsvorteile mit vorkompilierten LINQ-Queries

Um Geschwindigkeitsvorteile bei der Verwendung von LINQ zu genießen, sollte man einen Blick auf Precompiled Linq Queries werfen.

Hier ein kleines Beispiel, wie der vorkompilierte Query erstellt und verwendet wird.

Ein unkompilierter Query:

1
2
3
var customers = from c in CustomerContext.customer
              where c.lastName.Contains("Pri")
              select c;

Nachfolgend ein kompilierter Query:

Die Variable welche den vorkompilierten Query speichern soll, definieren wir wie folgt:

1
public readonly Func<CustomerContext, string, IQueryable<Customer>> getCustomersByName;

Und mit Zuweisung sieht das ganze wie folgt aus:

1
2
3
4
5
getCustomersByName =
            CompiledQuery.Compile<CustomerContext, string, IQueryable<Customer>>((CustomerContext context, lastName)
                => from c in context.Customer 
                   where c.LastName.Contains(lastName) 
                   select c);

Und verwendet wird das ganze später dann wie folgt:

1
var customers = getCustomersByName.Invoke(CustomerContext, "Pri");

by Mario Priebe

LINQ Tools

ThinqLinq stellt einige nützliche Tools, kategorisiert nach Samples, Profiler, Desginer, Code Generatoren und Provider, rund um LINQ zusammen

Auf SharpToolbox sind weitere nette Tools zu finden.

linq

by Mario Priebe

Mit LINQ2XML innerhalb einer foreach serialisieren

Ziel dieses HowTo’s ist es, mehrere Daten aus einem Service (hier in dem Beispiel aus einem Mock) via LINQ in eine XML zu schreiben (serialisieren).

Die XML soll folgendermaßen aussehen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Localization>
  <Module id="Customers">
    <CultureCode>de-DE</CultureCode>
    <Key>General</Key>
    <Value>Allgemein</Value>
  </Module>
  <Module id="Customers">
    <CultureCode>en-EN</CultureCode>
    <Key>General</Key>
    <Value>General</Value>
  </Module>
  <Module id="Customers">
    <CultureCode>de-DE</CultureCode>
    <Key>Customer</Key>
    <Value>Kunde</Value>
  </Module>
</Localization>

Dazu inizialisiere ich mir zu erst den Datenpool, in diesem Fall benutze ich eine Klasse die mir ein paar Mock-Objekte bereitstellt.

1
LocalizationServiceMock lm = new LocalizationServiceMock();

Dann erstelle ich mir das erste XML Element “Localization”, welches weitere Elemente beinhalten soll.

1
XElement moduleElement = new XElement("Localization");

Nun iteriere ich durch die Liste von Objekten die ich von meinem Mock bekomme und füge dem oben erstellten “moduleElement” die Daten aus dem Mock, als jeweils neues Element hinzu.

1
2
3
4
5
6
7
8
9
foreach (LocalizationServiceMock.TranslatedString translatedString in lm.GetTranslatedStrings())
{
  moduleElement.Add(new XElement("Module", new XAttribute("id", translatedString.Module),
        new XElement("CultureCode", translatedString.CultureCode),
        new XElement("Key", translatedString.Key),
        new XElement("Value", translatedString.Value)
        )
  );
}

Zum Schluss wird das Ganze noch in ein XDocument geschrieben

1
2
3
4
var localizationService = new XDocument(
  new XDeclaration("1.0", "UTF-8", "yes"),
    moduleElement
 );

und gespeichert:

1
localizationService.Save("Services/LocalizationService.xml");

Fertig sieht das folgendermaßen aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void WriteXml()
{
  LocalizationServiceMock lm = new LocalizationServiceMock();
  XElement moduleElement = new XElement("Localization");
 
  foreach (LocalizationServiceMock.TranslatedString translatedString in lm.GetTranslatedStrings())
  {
    moduleElement.Add(new XElement("Module", new XAttribute("id", translatedString.Module),
          new XElement("CultureCode", translatedString.CultureCode),
          new XElement("Key", translatedString.Key),
          new XElement("Value", translatedString.Value)
          )
    );
  }
  var localizationService = new XDocument(
    new XDeclaration("1.0", "UTF-8", "yes"),
      moduleElement
   );
  localizationService.Save("Services/LocalizationService.xml");
}

Viel Spass beim entwickeln : )