Mehr von Jürgen Gutsch

Mehr von Jürgen Gutsch

Empfehlungen von Jürgen Gutsch

Blog-Empfehlungen von Jürgen Gutsch

Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

Jürgen Gutsch

ASP.NET und mehr...
Ein Blick auf das Entity Framework 4

Angeregt durch ein aktuelles Projekt, musste ich mir das Entity Framework 4 (Microsofts OR-Mapper) anschauen. Bisher hatte ich es vermieden, da ich der Meinung war, dass ich die nötigen Mappings nur über den Designer mit viel Magie und wildem herumgeklicke herstellen kann. Allerdings halte ich es für wichtig, dass die Entities, die ich in meinen Projekten benötige, nicht autogeneriert sind, bzw. nicht vom OR-Mapper generiert werden, da dadurch unnötige Abhängigkeiten zum OR-Mapper entstehen oder unnötige Objekt-Mappings gemacht werden müssen.

Üblicherweise halte ich meine Entities in einem Projekt, das von allen anderen Projekten referenziert wird, die mit diesen Entities arbeiten. Mit NHibernate ist das auch problemlos möglich.

BTW: Ich bin ein großer Fan von NHibernate und nutze diesen OR-Mapper bisher in fast jedem großen Projekt.

Ich möchte also meine Entities wie folgt aufbauen:

public class Customer : EntityBase
{
    [StringLength(150)]
    [Required]
    public string Name { get; set; }
    [StringLength(100)]
    [Required]
    public string Street { get; set; }
   
    [StringLength(5)]
    [Required]
    [RegularExpression("^[0-9]{4,5}$")]
    public string Postalcode { get; set; }
}

EntityBase ist eine Basisklasse, welche die Id bereitstellt, Equals überschreibt, etc. Die hier sichtbaren Attribute stammen von den DataAnnotations und werden zur Validierung genutzt.

Würde ich jetzt das EF wie gewohnt einsetzen, müsste ich z. B. per AutoMapper von den generierten Entities auf meine Mappen. Das möchte ich nicht, bzw. müsste es mit NHibernate auch nicht tun.

DbContext

Nun war es heute René Leupold der mir mit seinem Blog http://databinding.net den entscheidenden Tipp für den DbContext gab. Mit dem DbContext ist es möglich das Entity Framework ähnlich wie NHibernate zu verwenden.

Hilfreich ist auch die Artikelserie “Using DbContext in EF 4.1” im ADO.NET Team Blog

Der DbContext ist ab EF 4.1 verfügbar. Ich selber habe mir für diese Beispiele die EntityFramework.dll 4.2.0.0 per NuGet referenziert.

Das Mapping

Was wir zusätzlich benötigen ist ein Mapping, das hier per Fluent API per C# gesetzt wird:

internal class CustomerMapping : EntityTypeConfiguration<Customer>
{
    public CustomerMapping()
    {
        Property(x => x.Name)
            .HasMaxLength(200)
            .IsVariableLength()
            .IsUnicode()
            .IsOptional();
        Property(x => x.Postalcode)
            .HasMaxLength(30)
            .IsVariableLength()
            .IsUnicode()
            .IsOptional();
    }
}

Genutzt wird die Konfiguration dann im DbContext:

public class DataContext : DbContext
{
    public IDbSet<Customer> Customers { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Configurations.Add(new CustomerConfig());
    }
}

Die Ähnlichkeit mit NHibernate ist an dieser Stelle eindeutig und ich habe meine gewünschte Trennung zwischen den Entities und dem OR-Mapper.

Die Connection

Interessant ist, dass die Verbindung zur Datenbank über den Constructor der Basisklasse DbContext gesetzt werden kann oder aber per Konvention:

<connectionStrings>
    <add name="DataContext"
         providerName="System.Data.SqlClient"
         connectionString="Data Source=[…]" />    
</connectionStrings>

Der Name des ConnectionStrings muss einfach so heißen wie der entsprechende DbContext

Benutzen

Wenn die DB schon existiert ist das im Prinzip auch schon alles um mit den Daten zu arbeiten:

[Test]
public void SetAndLoadCustomerFromDataBase()
{
    IEnumerable<Customer> customers;
    using (var context = new DataContext())
    {
        context.Customers.Add(new Customer
                                  {
                                      Id = Guid.NewGuid(),
                                      Name = "Hallo Welt",
                                      Street = "Hallo Street 2",
                                      Postalcode = "12345"
                                  });
        context.SaveChanges();
    }
    using (var context = new DataContext())
    {
        customers = context.Customers.Select(c => c).ToList();
    }
    Assert.That(customers.Count(), Is.GreaterThan(0));
}

Das Mapping wird erzeugt, wenn das erste mal der DataContext instanziert wird. Es wird relativ viel mit Lazy<T> gearbeitet, so dass das Debugging der ergebnislisten nicht immer ganz einfach ist.

 

Demo

Eine Demo werde ich in den nächsten Tagen hier anhängen. Die vorhandenen Projekte muss ich erst noch anonymisieren.

Fazit

Mit dem DbContext scheint das EntityFramework doch noch ein ganz passables Werkzeug und eine ernstzunehmende Alternative zum NHibernate zu sein.

Posted: Dienstag, 3. Januar 2012 22:18 von Jürgen Gutsch

Kommentare

Keine Kommentare

Anonyme Kommentare sind nicht zugelassen