「プロジェクト」と「テンプレート」の間に多対1の関連付けがあります。
プロジェクトには「テンプレート」タイプのプロパティがあります。
関連付けは双方向ではありません (「テンプレート」は「プロジェクト」を認識しません)。
「プロジェクト」の関連付けのエンティティ マッピングは次のとおりです。
this.HasOptional(p => p.Template);
テンプレートを指定せずに「プロジェクト」を作成すると、null が「プロジェクト」テーブルの「TemplateId」列に正しく挿入されます。
テンプレートを指定すると、テンプレートの ID が正しく挿入されます。生成された SQL:
update [Projects]
set [Description] = '' /* @0 */,
[UpdatedOn] = '2011-01-16T14:30:58.00' /* @1 */,
[ProjectTemplateId] = '5d2df249-7ac7-46f4-8e11-ad085c127e10' /* @2 */
where (([Id] = '8c1b2d30-b83e-4229-b0c3-fed2e36bf396' /* @3 */)
and [ProjectTemplateId] is null)
ただし、テンプレートを変更しようとしたり、null に設定したりしても、templateId は更新されません。生成された SQL:
update [Projects]
set [UpdatedOn] = '2011-01-16T14:32:14.00' /* @0 */
where ([Id] = '8c1b2d30-b83e-4229-b0c3-fed2e36bf396' /* @1 */)
ご覧のとおり、TemplateId は更新されていません。
これは私には意味がありません。コードで "Project" の "Template" プロパティを明示的に null に設定しようとしましたが、コードをステップ実行すると、まったく効果がないことがわかります。
ありがとう、ベン
[アップデート]
当初、これは DbContext に IDbSet プロパティを追加するのを忘れたことが原因だと考えていました。ただし、さらにテストしたので、よくわかりません。以下は、完全なテスト ケースです。
public class PortfolioContext : DbContext, IDbContext
{
public PortfolioContext(string connectionStringName) : base(connectionStringName) { }
public IDbSet<Foo> Foos { get; set; }
public IDbSet<Bar> Bars { get; set; }
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) {
modelBuilder.Configurations.Add(new FooMap());
modelBuilder.Configurations.Add(new BarMap());
base.OnModelCreating(modelBuilder);
}
public new IDbSet<TEntity> Set<TEntity>() where TEntity : class {
return base.Set<TEntity>();
}
}
public class Foo {
public Guid Id { get; set; }
public string Name { get; set; }
public virtual Bar Bar { get; set; }
public Foo()
{
this.Id = Guid.NewGuid();
}
}
public class Bar
{
public Guid Id { get; set; }
public string Name { get; set; }
public Bar()
{
this.Id = Guid.NewGuid();
}
}
public class FooMap : EntityTypeConfiguration<Foo>
{
public FooMap()
{
this.ToTable("Foos");
this.HasKey(f => f.Id);
this.HasOptional(f => f.Bar);
}
}
public class BarMap : EntityTypeConfiguration<Bar>
{
public BarMap()
{
this.ToTable("Bars");
this.HasKey(b => b.Id);
}
}
そしてテスト:
[Test]
public void Template_Test()
{
var ctx = new PortfolioContext("Portfolio");
var foo = new Foo { Name = "Foo" };
var bar = new Bar { Name = "Bar" };
foo.Bar = bar;
ctx.Set<Foo>().Add(foo);
ctx.SaveChanges();
object fooId = foo.Id;
object barId = bar.Id;
ctx.Dispose();
var ctx2 = new PortfolioContext("Portfolio");
var dbFoo = ctx2.Set<Foo>().Find(fooId);
dbFoo.Bar = null; // does not update
ctx2.SaveChanges();
}
これは SQL CE 4 を使用していることに注意してください。