Entity Framework – Erste Schritte und Erfahrungen

Meinen Einstieg ins Entity Framework von Microsoft hatte ich bereits vor etwa einem Jahr und seitdem kann ich mir keinen schnelleren und einfacheren Weg mehr vorstellen, um „mal eben“ einen Datenbankzugriff zu realisieren – kein Abstimmen von SQL-Befehlen auf Entity-Klassen, kein Verwalten von Fremdschlüsseln, kein explizites DDL-Skript zur Anlage der Tabellen. Dank des Entity Frameworks kann ich weiter in C# arbeiten, mich auf meine Klassen und Geschäftslogik konzentrieren und das DB-Management delegieren.

Erste Schritte

Das Entity Framework (EF) lässt sich leicht fast jedem Projekt mit dem NuGet-Paket-Manager hinzufügen.

Da ich den „Code First“-Ansatz, bei dem die Klassen automatisch in Tabellen umgewandelt werden, bevorzuge, konzentriere ich mich auf den Entwurf meiner Datenklassen und modifiziere sie leicht, um dem EF Hinweise zu geben, was wie umgesetzt werden soll.

Ein kleines Beispiel

Aus den beiden folgenden Klassen…

public class Diagram
{
    public Guid Id { get; set; }
    public String Name { get; set; }
    public ICollection<Symbol> ContainedSymbols { get; set; }
}

public class Symbol
{
    public Guid Id { get; set; }
    public String Name { get; set; }
    public Diagram ContainingDiagram { get; set; }
}

wird…

public class Diagram
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    public String Name { get; set; }

    public virtual ICollection<Symbol> ContainedSymbols { get; set; }
}

public class Symbol
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    public String Name { get; set; }

    public Guid ContainingDiagramId { get; set; }

    [ForeignKey("ContainingDiagramId")]
    public virtual Diagram ContainingDiagram { get; set; }
}

Das Attribut „Key“ definiert den Primärschlüssel, „Required“ legt fest, dass dieser Wert in der Datenbank nicht NULL sein darf, und „ForeignKey“ definiert die Schlüsseleigenschaft, über die eine „Navigationseigenschaft“ aufgelöst werden soll (oder alternativ die Navigationseigenschaft, die die so gekennzeichnete Schlüsseleigenschaft auflöst). Weiteres dazu findet sich online unter dem Begriff „Code First Data Annotations„.

Bleibt noch der Hinweis, dass die Kennzeichnung der „Navigationseigenschaften“ (Eigenschaften, die „Entitäten“/Datenobjekte miteinander verbinden) mit virtual dafür sorgt, dass das EF „lazy loading“ einsetzen kann, um den Inhalt bereitzustellen, sprich: die Daten werden nicht sofort bereitgestellt, sondern erst abgerufen, wenn sie wirklich benötigt werden.

Einen Kontext erstellen

Nachdem die Datenklassen wie oben beschrieben bereitstehen, fehlt nur noch der DbContext, der den Zugriff auf die Datenbank kapselt:

public class DiagramContext : DbContext
{
    public DbSet<Diagram> Diagrams { get; set; }

    public static void PopulateDatebase()
    {
        using (DiagramContext dc = new DiagramContext())
        {
            Diagram dgm = new Diagram();
            dgm.Id = Guid.NewGuid();
            dgm.Name = "Ein erstes Diagramm";

            dc.Diagrams.Add(dgm);
            dc.SaveChanges();
        }
    }
}

Erfahrungen

Bislang habe ich meinen DbContext in jeder ASP.NET MVC-Action neu erstellt und mit using geklammert. Inzwischen hat sich aber gezeigt, dass beim weiterreichen von Abfrageergebnissen an Views Probleme entstehen können, wenn die Abfragen nicht mit .ToArray() oder .ToList() komplett ausgeführt wurden, da nach dem verlassen des using-Blocks der DbContext bereits „disposed“ ist. Ein besserer Weg ist das definieren eines DbContext-Attributs in der MVC-Controller-Klasse, das im Konstruktor (oder direkt) initialisiert und in einer Dispose()-Überschreibung „disposed“ wird.

RPG Summer

Typically, summer means few or no rpg sessions to me as vacation, birthdays, outdoor events, etc. take weekend priority in our lives. But while America was preparing for GenCon I decided to contribute some of my freetime to the roleplaying community and released three free fantasy rpg apps:

  • Random Magic Armor allows you to randomly generate or create specific pieces of magic armor,
  • Random Magic Weapon does just that for melee and ranged weapons, and
  • Grimoire puts a searchable, filterable, groupable list of magical spells right at your fingertips.

All these apps are subject to the Open Game License, feature Open Game Content directly accessible from within the app, and are based on the Pathfinder Roleplaying Game Reference Document.

Notice

Pathfinder is a registered trademark of Paizo Publishing, LLC. Pathfinder Roleplaying Game is a trademark of Paizo Publishing, LLC

Metro App: Breite der Items im ListView kontrollieren

Standardmäßig haben die Elemente in einem ListView eine Breite, die ihrem Inhalt entspricht und werden durch den ListView selbst nur in ihrer maximalen Breite beschränkt. Wenn allerdings alle Elemente die gleiche Breite, vorzugsweise die maximal zulässige Breite eines Elements im ListView, haben sollen, dann muss der ItemContainerStyle angepasst werden:

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</ListView.ItemContainerStyle>

Random Crash

System.Random ist nicht Thread-sicher! Bei „gelichzeitigem“ Aufruf aus verschiedenen Threads, gibt Next() irgendwann nur noch „0“ zurück. Um dies zu verhindern, muss entweder jeder Aufruf an eine Random-Instanz durch „lock ()“ umschlossen werden:

lock (MyRandomMember)
{
    MyRandomMember.Next();
}

oder jeder Thread erhält eine eigene Random-Instanz, was bequem über das Attribut „ThreadStatic“ möglich ist:

[ThreadStatic]
private static Random _myRandomMember;

private static Random MyRandomMember
{
    get { return _myRandomMember ?? (_myRandomMember = new Random()); }
}

SASS & Compass – komplexes CSS einfach managen

Compass ist ein großartiges Tool, um ein Webprojekt auch nachträglich mit Foundation „aufzupeppen“. Außerdem erledigt es nebenbei alle nötigen Arbeiten, um Anpassungen am Framework sofort als CSS bereitzustellen. Und wenn man schon mal dabei ist, kann man auch gleich SASS nutzen, um seine eigenen Styles einfacher zu managen.

Compass installieren

Compass benötigt Ruby und ist dann sehr einfach zu installieren:

gem update --system
gem install compass

Bestehendes ASP.NET MVC4 -Projekt erweitern

Um ein typisches Webprojekt um Compass-Unterstützung zu erweitern, müssen lediglich die folgenden Befehle ausgeführt werden:

cd <myproject>
compass create --bare --sass-dir "Content\sass"
    --css-dir "Content" --javascripts-dir "Scripts"
    --images-dir "Content\images"

Verzeichnisüberwachung starten

Mit dem Befehl „compass watch“ kann das akuelle Verzeichnis überwacht werden – der Watcher startet aber nur, wenn es schon eine *.SASS oder *.SCSS Datei zu überwachen gibt, weswegen vorher im Verzeichnis „.\Content\sass“ z.B. eine Datei „Styles.scss“ händisch angelegt werden sollte.

Foundation mit Compass installieren

Wie auf der Foundation-Homepage beschrieben, ist es sehr einfach, Foundation zu installieren:

gem install zurb-foundation

oder zu aktualisieren:

gem update zurb-foundation

Ist ein Projekt bereits für Compass eingerichtet, liegt eine „config.rb“ Datei im Projektverzeichnis. Diese muss (am besten am Anfang) um den Eintrag require "zurb-foundation" ergänzt werden, was dann die Ausführung des folgenden Befehls ermöglicht:

compass install foundation

Und damit ist das Projekt dann auch schon bereit für den Einsatz von Foundation!

Simple Dice Roller R3: Deutsch!

Das dritte Release des Simple Dice Rollers steht an – auch wenn es eigentlich nur ein Service Release ist und die Quellen von Store- und Phone-App vereinheitlicht, so gibt es doch eine Neuerung: Das Release 3 wird auf deutschen Rechner in deutscher Sprache dargestellt! Für alle weiteren Sprachen wird nach wie vor Englisch verwendet.

Falls jemand weitere Übersetzungen beisteuern will, dann bitte gerne an Support@JochenLinnemann.de wenden!

XAML: Unterschiede in der Namespace-Deklaration Phone / Store Apps

Wie ich gerade feststellen musste, arbeiten in Visual Studio 2012 die XAML-Editoren/-Compiler für WinStore-Apps und WinPhone 8-Apps unterschiedlich, wenn es um die Referenzierung von Klassen im eigenen Assembly geht. Während bei Phone-Apps die Angabe xmlns:local=“clr-namespace:JochenLinnemann.DiceRoller“ durchaus akzeptiert wird, muss es bei Store-Apps xmlns:local=“using:JochenLinnemann.DiceRoller“ heißen.