Ich versuche den EF5 CodeFirst und kann das einfache Setup nicht zum Laufen bringen ;(
Ich habe zwei Klassen Foo und Bar, wobei Bar eine Nachschlagetabelle darstellt.
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Bar Bar { get; set; }
}
public class Bar
{
public int Id { get; set; }
public string Description { get; set; }
}
public class MyDbContext : DbContext
{
static MyDbContext()
{
Database.SetInitializer<MyDbContext>(null);
}
public MyDbContext(): base("testEF"){}
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bars { get; set; }
}
Jetzt habe ich eine statische Klasse erstellt, die als DataAccess Layer dient - in der realen Anwendung wird sie auf einer anderen physikalischen Ebene liegen
public static class DataAccess
{
public static Bar GetBarById(int id)
{
using (var db = new MyDbContext())
{
return db.Bars.SingleOrDefault(b => b.Id == id);
}
}
public static Foo InsertFoo(Foo foo)
{
using (var db = new MyDbContext())
{
db.Foos.Add(foo);
db.SaveChanges();
}
return foo;
}
}
Ich initialisiere die DB mit der Seed-Methode:
internal sealed class Configuration : DbMigrationsConfiguration<testEF.MyDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(testEF.MyDbContext context)
{
context.Bars.AddOrUpdate(
new Bar { Description = "Bar_1" },
new Bar { Description = "Bar_2" }
);
}
}
Dadurch werden zwei Datensätze in der Tabelle Bars erstellt. So weit, so gut...
Hier ist meine Hauptfunktion
static void Main(string[] args)
{
var bar1 = DataAccess.GetBarById(1);
var foo = new Foo
{
Name = "Foo_1",
Bar = bar1
};
DataAccess.InsertFoo(foo);
}
Nach den App-Runen gibt es einen Eintrag in der Foos-Tabelle:
Id Name Bar_Id
1 Foo_1 3
Warum ist Bar_Id 3? Die EF hat tatsächlich einen neuen Datensatz in die Tabelle Bars eingefügt!
Id Description
1 Bar_1
2 Bar_2
3 Bar_1
Was mache ich falsch?
UPDATE: Ich habe eine Abhilfe gefunden - die Bar-Eigenschaft vor dem Einfügen des Datensatzes anzuhängen:
public static Foo InsertFoo(Foo foo)
{
using (var db = new MyDbContext())
{
db.Bars.Attach(foo.Bar);
db.Foos.Add(foo);
db.SaveChanges();
}
return foo;
}
Es funktioniert zwar jetzt, aber das ist eher ein Hack als eine echte Lösung... In der realen Anwendung könnte die Komplexität der Objekte zu einem großen Problem werden. Ich bin offen für bessere Lösungen