Biggle's Blog

Web- und Software Development

by Mario Priebe

BASTA! on Tour – Architecture & Best Practices + Gewinnspiel

Vom 19. bis 20. Mai 2011 veranstaltet die Entwickler Akademie in Kooperation mit dem dot.net Magazin die nächste BASTA! on Tour – Architecture & Best Practices – diesmal in Düsseldorf. Das Tochterevent der BASTA! – der größten unabhängigen .NET-Konferenz bietet zwei Tage lang tiefgehendes Know-how zum Thema Architektur und Best Practices in der .NET-Welt.

Insgesamt vier ganztägige Workshops, acht Sessions und ein Speaker Panel mit den bekannten .NET-Experten Dr. Holger Schwichtenberg, Jörg Neumann, Manfred Steyer und Christian Wenz stehen zur Auswahl.

Das Trainingsevent vermittelt am ersten Tag die Grundlagen von WPF, WCF, Entity Framework und jQuery. Der zweite Tag baut auf den Inhalten der Workshops auf und steht ganz im Zeichen von Architekturfragen, Patterns, Tipps, Tricks und Best Practices.

Alle Infos auf www.basta-on-tour.de

Gewinnspiel

Warst Du schon einmal auf der Basta, Basta Spring oder Basta on Tour? Wenn ja, wie sind Deine Erfahrungen, würdest du wieder hingehen, oder jemand anderes empfehlen?

Unter den Kommentaren, verlose ich zusammen mit der Entwickler Akademie ein Abonnement für 1 Jahr für das dotnet Magazin.

Der Gewinner wird über random.org ermittelt. Das Gewinnspiel endet zum 30.April 2011 20Uhr.

by Mario Priebe

SQLite Datenbanken in C# Applikationen verwenden

System.Data.SQlite aus dem Hause phxsoftware bietet eine Schnittstelle zur Verwendung von portablen Datenbanken im SQLite Format. Im Folgenden möchte ich zeigen, wie man diese auf unterschiedlicher Weise, in C# Applikationen verwenden kann.

Um eine SQLite Datenbank zu erstellen, gibt es eine Menge von Managementapplikationen oder auch Browsererweiterungen, z.b für den Firefox. Ich verwende, um mir erstmalig eine Datenbank zu erstellen, den kostenlosen SQLiteBrowser. Die erstellte Datenbank speichere ich dann in meinem TestProjekt, mit welchem ich auf diese zugreifen möchte.

Als erstes holen wir uns die Installation oder die Binaries. Je nach Architektur wird dann im Projekt, auf die entsprechende dll referenziert. Ich verwende die System.Data.SQLite.dll für x86, welche sich im bin Ordner befindet.

SQLiteCommand

Im ersten Beispiel, verwende ich die SQLiteCommand-Klasse, um auf die Datenbank zugreifen.

Nach dem Einbinden des Namespace “using System.Data.SQLite;” stehen uns die Klassen SQLiteConnection und SQLiteCommand zur Verfügung. (Mehr benötigen wir erstmal in unserem Beispiel nicht.)

Den Pfad, zur zuvor angelegten Datenbank lege ich in der app.config fest, damit dieser konfigurierbar bleibt:

1
2
3
4
5
<configuration>
  <appSettings>
    <add key="DATASOURCE" value="../../DataBase/data" />
  </appSettings>
</configuration>

im Code dann (namens DataProvider.cs), holen wir uns den Pfad über den ConfigurationManager in eine KlassenVariable. Hier muss explizit auf System.Configuration referenziert werden

1
private string DataSource = ConfigurationManager.AppSettings.Get("DATASOURCE");

Das Speichern, Emitteln und Löschen erledigen wir über das SQLiteCommand. Zum Öffnen und Schließen der SQLiteConnection habe ich mir zwei Methoden geschrieben:

1
2
3
4
5
6
7
8
SQLiteConnection connection;
 
private void OpenConnection()
{
    connection = new SQLiteConnection();
    connection.ConnectionString = "Data Source=" + DataSource;
    connection.Open();
}
1
2
3
4
5
private void CloseConnection()
{
    connection.Close();
    connection.Dispose();
}

Speichern von Einträgen

1
2
3
4
5
6
7
8
9
10
11
OpenConnection();
 
using (var command = new SQLiteCommand(connection))
{
    command.CommandText = string.Format("INSERT INTO Entities (Beschreibung, HtmlName, Unicode, Zeichen) VALUES('{0}', '{1}', '{2}', '{3}')",
                    entity.Beschreibung, entity.HtmlName, entity.Unicode, entity.Zeichen);
 
    command.ExecuteNonQuery();
}
 
CloseConnection();

Ermitteln von Einträgen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
OpenConnection();
 
List<HtmlEntity> entities = new List<HtmlEntity>();
using (var command = new SQLiteCommand(connection))
{
    command.CommandText = "SELECT * FROM Entities";
 
    using (SQLiteDataReader reader = command.ExecuteReader())
    {
        while (reader.Read())
        {
            entities.Add(new HtmlEntity
            {
                Beschreibung = reader[0].ToString(),
                HtmlName = reader[1].ToString(),
                Unicode = reader[2].ToString(),
                Zeichen = reader[3].ToString()
 
            });
        }
        reader.Close();
    }
}
 
CloseConnection();

Löschen von Einträgen

1
2
3
4
5
6
7
8
9
10
11
OpenConnection();
 
using (var command = new SQLiteCommand(connection))
{
    command.CommandText = string.Format("DELETE FROM Entities WHERE Beschreibung = '{0}' AND HtmlName = '{1}' AND Unicode = '{2}' AND Zeichen =  '{3}'",
        entity.Beschreibung, entity.HtmlName, entity.Unicode, entity.Zeichen);
 
    command.ExecuteNonQuery();
}
 
CloseConnection();

Achtung! Es ist möglich, das die SQLite Assembly sich nicht mit dem 4.0 .NET  kompilieren lässt. (Mixed mode assembly is built against version ‘v2.0.50727′ of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information), hier kann man sich aber mit folgendem Eintrag, innerhalb des “configuration-Knoten” in der app.config behelfen

1
2
3
<startup useLegacyV2RuntimeActivationPolicy="true">
	<supportedRuntime version="v4.0"/>
</startup>

Tipp via: stackoverflow


SQLite & Entity Framework

Es ist auch möglich, eine SQLite Datenbank als Datensource für ein Entity-Framework-Model anzugeben. Das erstelle Entity FrameworkModel stellt uns nun den Kontext bereit, Einträge zu persistieren, zu ermitteln und zu löschen.

Eintrag speichern

1
2
3
4
5
6
7
8
public void  InsertData(HtmlEntity entity)
{
    using (var context = new HtmlEntityEntities())
    {
        context.AddToEntities(entity);
        context.SaveChanges();
    }
}

Einträge ermitteln

1
2
3
4
5
6
7
8
9
10
11
12
13
public List<HtmlEntity> GetAllHtmlEntities()
{
    List<HtmlEntity> entities;
 
    using (var context = new HtmlEntityEntities())
    {
        entities = (from e in context.Entities
                    select e).ToList();
 
    }         
 
    return entities;
}

Eintrag löschen

1
2
3
4
5
6
7
8
9
10
11
public void DeleteData(HtmlEntity entity)
{
    using (var context = new HtmlEntityEntities())
    {
        HtmlEntity obj = (HtmlEntity)context.GetObjectByKey(entity.EntityKey);
 
 
        context.DeleteObject(obj);
        context.SaveChanges();
    }
}

LINQ to SQLite

Wie wir an den EF Methoden gesehen haben, können wir nun einfach mit LINQ die Operationen ausführen.

Am Beispiel “Einträge ermitteln” wurde LINQ bereits verwendet, diese kann dann natürlich auch durch eine Where-Klausel erweitert werden:

1
2
3
4
5
6
using (var context = new HtmlEntityEntities())
{  
    return (from e in context.Entities                        
            where e.Beschreibung == keyword                      
            select e).FirstOrDefault();
}

Auch wenn es so scheint, dass die System.Data.SQLite.Linq.dll wichtig für den Zugriff mit LINQ ist, wir benötigen diese dll nicht, denn durch das generieren des EF Models, steht uns hier LINQ aus dem Framework zu Verfügung.

Fragen? Einfach in den Kommentaren damit. Viel Spaß beim entwickeln : )

by Mario Priebe

Mehrfachvererbung – Ein Beispiel in C#

Angestichelt durch Ilker sein Blogpost, bin ich der Sache mit der Mehrfachvererbung unter .NET mal etwas auf den Grund gegangen. Der Ansatz mit Mixin, Interfaces und ExtensionMethods scheint ja schon seit .NET 3.0 zu bestehen und scheint mir bisher auch der Beste zu sein. Einen weiteren schönen Artikel kann man bei Galileo Computing lesen.

Hier ein Beispiel wie ich das verstanden habe und umsetzen würde.

Interfaces

1
2
3
4
public interface IMixinDateTime
{ }
public interface IMixinOneMoreInterface
{ }

ExtensionMethods

1
2
3
4
5
6
7
8
9
10
11
12
public static class MixinExtensionMethods
{
    public static int GetYearDiff(this IMixinDateTime mxDateMethod, DateTime dateTime)
    {
        return new DateTime(DateTime.Now.Subtract(dateTime).Ticks).Year - 1;
    }
 
    public static void OneMoreMethod(this IMixinOneMoreInterface mxOneMoreMethod)
    {
        //implement method here ...
    }
}

Klassen, welche die Interfaces erben (ggf. implementieren)

1
2
3
4
5
6
7
8
9
public class Car : IMixinDateTime
{
    public DateTime Baujahr { get; set; }
}
 
public class Person : IMixinDateTime, IMixinOneMoreInterface
{
    public DateTime Birthday { get; set; }
}

Verwendung

1
2
3
4
5
6
7
8
9
Person person = new Person();
person.Birthday = new DateTime(1973, 01, 23);
var personAge = person.GetYearDiff(person.Birthday);
 
Car car = new Car();
car.Baujahr = new DateTime(2000, 01, 01);
var carAge = car.GetYearDiff(car.Baujahr);
 
person.OneMoreMethod();

Da beliebig viele Interfaces geerbt werden können, erschließt sich hier, wie das Prinzip funktioniert. Weitere Meinungen, Ergänzungen oder Ansätze sind gerne als Kommentar gesehen.

Viel Spaß beim entwickeln : )

by Mario Priebe

Biggle ist kein Palindrom

Eine kleine Übungsaufgabe für mich, die es zu lösen gab. Es sollte heraus gefunden werden, ob es sich bei einem String um ein Palindrom handelt.

Mein Lösungsansatz lautet wie folgt:
Ich befreie zunächst die Buchstaben von Sonder- und Leerzeichen und konvertiere alle Zeichen zu Kleinbuchstaben. Dann durchlaufe ich eine for-Schleife mit eine Länge des Stringparameters.

Ich zerlege den String in ein CharArray und vergleiche innerhalb der Schleife, den vorderen mit den letzten Buchstaben. Sind diese gleich wird der nächste vordere und der nächste hintere Buchstabe verglichen. Das geht so lange bis diese sich in der Mitte treffen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public static class ExtensionMethods
{
    public static bool IsPalindrome(this string value)
    {
        //von Leer- und Sonderzeichen befreien
        value = value.ToLower().RemoveSpecialCharacters();
 
        int minValue = 0;
        int maxValue = value.Length - 1;
 
        var charArray = value.ToCharArray();
 
        for (int i = 0; i < value.Length - 1; i++)
        {
            if (charArray[minValue] == charArray[maxValue])
            {
                minValue++;
                maxValue--;
                continue;
            }
            else
                return false;
        }
        return true;
    }
 
    public static string RemoveSpecialCharacters(this string value)
    {
        return Regex.Replace(value, @"[^a-zA-Z0-9]", string.Empty);
    }
}

Verwendung:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Program
{
    static void Main(string[] args)
    {
        PalindromFactory factory = new PalindromFactory();
        var palindrome = factory.GetPalindrome();
        string output = "{0} ist {1}ein Palindrom";
 
        foreach (var palindrom in palindrome)
        {
            Console.WriteLine(String.Format(output, palindrom, palindrom.IsPalindrome() ? "" : "k"));
        }
 
        var palindromSaetze = factory.GetPalindromSaetze();
        foreach (var palindrom in palindromSaetze)
        {
            Console.WriteLine(String.Format(output, palindrom, palindrom.IsPalindrome() ? "" : "k"));
        }
    }
}

Ich hoffe ich habe nichts vergessen, getestet jedoch habe ich diese Methode mit der Liste deutscher Palindrome aus Wikipedia. Nicht-Palindrome natürlich mit einbegriffen : )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/// Stellt eine Sammlung von Palindrome und Palindromsätze bereit
/// Quelle Wikipedia
/// http://de.wikipedia.org/wiki/Liste_deutscher_Palindrome
public class PalindromFactory
{
    private List<string> Palindrome { get; set; }
 
    public List<string> GetPalindrome()
    {
        Palindrome = new List<string>
        {
            "Aha",
            "Amokoma",
            "Amoralaroma",
            "Anina",
            "Anna",
            "Annasusanna",
            "Aua",
            "Bob",
            "Bub",
            "Burggrub",
            "Biggle", //kein Palindrom
            "Mario", //kein Palindrom
            "Mongognom",
            "Nebelleben",
            "neben",
            "Neffen",
            "nennen",
            "netten",
            "netzten",
            "Neozoen",
            "nun",
            "Omo",
            "Otto",
            "Priebe" //kein Palindrom
            };
 
        return Palindrome;
    }
 
    public List<string> GetPalindromSaetze()
    {
        Palindrome = new List<string>
        {
            "Die Liebe fleht: Helfe bei Leid!",
            "Die Liebe geht, hege Beileid!",
            "Die Liebe, ist sie Beileid?",
            "Die Liebe ist Sieger, rege ist sie bei Leid.",
            "Die Liebe ist Sieger, stets rege ist sie bei Leid.",
            "Die Niere bot Komik: nass sank im Oktober ein Eid.",
            "Die Rede — ist sie der Eid?",
            "Dreh Magiezettel um, Amulette zeig am Herd!",
            "Du, erfror Freud?",
            "Der Fred",
            "Eine güldne, gute Tugend: Lüge nie!",
            "Eine Horde bedrohe nie!",
            "Eine Hure ruhe nie.",
            "Eine Note betone nie.",
            "Eine so Kesse kose nie.",
            "Eine treue Familie bei Lima feuerte nie.",
            "Einhorn roh? Nie!",
            "Eins nutzt uns: Amore. Die Rederei da, die Rederei der Omas nutzt uns nie.",
            "Eis feil! Ei, wo Eis feil lief sie, o wie lief sie.",
            "Elietta hat Teile.",
            "Ella rüffelte Detlef für alle.",
            "Elly biss Sibylle.",
            "Emma, behend 'ne Hebamme!",
            "Emma, so litt Tilos Amme!",
            "Emmas Amme",
            "Er habe nie eine Bahre.",
            "Erhabene Bahre",
            "Erhöre nie eine Röhre.",
            "Erika feuert nur untreue Fakire.",
            "Erol, red nie in der Lore.",
            "Alles hat seine Zeit, nur die alten Weiber nicht.", //Kein Palindromsatz
            "Es eilt, immer ahnend Nebel, reger der Flegel Fred, reg' erlebend nen Harem mit Liese.",
        };
 
        return Palindrome;
 
    }
}

Für einen schnellen Verwendungszeck (weil man das auch so oft braucht oO)  habe ich das ganze als ExtensionMethod implementiert.

Wie schaut’s aus, hast du Verbesserungsvorschläge? Würdest du es anders machen, wenn ja wie? Du kannst im Kommentarfeld mit

<strong>var* </strong>deinCodeSnippet = 0;

posten.


Viel Spaß beim entwickeln : )


* = Var oder nicht var…

by Mario Priebe

Dotnet-Kick Button in WordPress einbinden II

Stefan Lieser hat zwar schon einmal ein CodeSnippet veröffentlicht, wie man den Dotnet-Kick Button in einem WordPress Blog einbindet, ich hab dieses kleine Snippet aber noch ein bisschen “verfeinert” : )

Es wird nun nicht nur der Link und der Titel des Artikels zu dotnet-kicks mit übertragen, sondern auch ein Teil vom Content, welcher im Beschreibungsfeld mit vorausgefüllt wird.

Hier kannst Du auch die Anzahl der Zeichen, die von Deinem Content abgeschnitten werden sollen mit angeben (atm im Code 160). Nun einfach nur noch die Kategorie auf dotnet-kick anwählen und speichern.

1
<a href="http://dotnet-kicks.de/kick/?url=<?php echo get_permalink() ?>&title=<?php the_title(); ?>&description=<?php $string = get_the_excerpt(); $newString = substr($string, 0, 160); $newString.= ' ...'; echo $newString; ?>"><img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=<?php echo get_permalink() ?>" alt="Kick it on dotnet-kicks.de" /></a>

Wenn Du den Content nicht abschneiden möchtest, dann benutzt du einfach folgenden Code:

1
<a href="http://dotnet-kicks.de/kick/?url=<?php echo get_permalink() ?>&title=<?php the_title(); ?>&description=<?php $string = get_the_excerpt(); ?>"><img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=<?php echo get_permalink() ?>" alt="Kick it on dotnet-kicks.de" /></a>

Ich glaub sogar, dass Jan Welker (Mitinitiator von dotnet-kicks) ein Truncate in der Artikelansicht mit eingebaut hat, also sollte normal das untere Snippet ausreichen…

Wie auch immer, viel Spass damit

Ich bin auch mal so frech und “kick” mich gleich mal selbst :D

by Mario Priebe

Entity Framework Model updaten …

… bringt meiner Meinung nach garnix*, das Model lieber gleich neu erstellen, das erspart ne Menge Frust und Ärger … ob EF4.0 etwas verlässlicher ist ?


* jedenfalls wenn man den Datentyp oder einen Spaltennamen ändert