EF5 CodeFirst を試していますが、簡単なセットアップが機能しません ;(
Foo と Bar の 2 つのクラスがあり、Bar はルックアップ テーブルを表します。
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; }
}
これで、DataAccess レイヤーとして機能する静的クラスを作成しました。実際のアプリケーションでは、異なる物理層に配置されます。
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;
}
}
シード メソッドで DB を初期化しています。
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" }
);
}
}
これにより、Bars テーブルに 2 つのレコードが作成されます。ここまでは順調ですね...
これが私の主な機能です
static void Main(string[] args)
{
var bar1 = DataAccess.GetBarById(1);
var foo = new Foo
{
Name = "Foo_1",
Bar = bar1
};
DataAccess.InsertFoo(foo);
}
アプリが実行された後、Foos テーブルにレコードがあります。
Id Name Bar_Id
1 Foo_1 3
なぜ Bar_Id は 3 なのですか? EF は実際に Bars テーブルに新しいレコードを挿入しました!
Id Description
1 Bar_1
2 Bar_2
3 Bar_1
私が間違っていることは何ですか?
更新: 回避策を見つけました - レコードを挿入する前に Bar プロパティを添付します:
public static Foo InsertFoo(Foo foo)
{
using (var db = new MyDbContext())
{
db.Bars.Attach(foo.Bar);
db.Foos.Add(foo);
db.SaveChanges();
}
return foo;
}
現在は機能していますが、これは有効なソリューションというよりはハックのようなものです...実際のアプリケーションでは、オブジェクトの複雑さが大きな問題になる可能性があります。私はより良い解決策を受け入れます