c# - Not updating discriminator when property type changes -
i've got entity has property that's abstract type. creates one-to-one relationship uses table-per-hierarchy inheritance. seems it's working correctly.
i can create item , set base
property concreteone
; saves correctly. however, when try update base
concretetwo
, ef updates base
record in database new user value, doesn't update discriminator type. data concretetwo
gets persisted, discriminator still says concreteone
.
the following simple example exposes problem
namespace consoleapplication1 { class program { static void main(string[] args) { app_start.entityframeworkprofilerbootstrapper.prestart(); database.setinitializer(new dropcreatedatabasealways<datacontext>()); // create our item concreteone base using (var context = new datacontext()) { var item = new item { base = new concreteone { name = "item", data = 3 } }; context.items.add(item); context.savechanges(); } // update base new concretetwo using (var context = new datacontext()) { var item = context.items.firstordefault(); var newbase = new concretetwo() { item = item, name = "item 3", user = new user { name = "foo" } }; // if don't set null, ef tries create new record in db causes pk exception item.base.item = null; item.base = newbase; // ef doesn't save discriminator, save user reference context.savechanges(); } // retrieve item -- ef thinks base still concreteone using (var context = new datacontext()) { var item = context.items.firstordefault(); console.writeline("{0}: {1}", item.name, item.base.name); } console.writeline("done."); console.readline(); } } public class datacontext : dbcontext { public dbset<item> items { get; set; } } public class user { public int id { get; set; } public string name { get; set; } } public class item { public int id { get; set; } public string name { get; set; } public virtual base base { get; set; } } public abstract class base { public int id { get; set; } public string name { get; set; } [required] public virtual item item { get; set; } } public class concreteone : base { public int data { get; set; } } public class concretetwo : base { public virtual user user { get; set; } } }
when changes saved, ef generates following sql:
update [dbo].[bases] set [name] = 'item 3' /* @0 */, [user_id] = 1 /* @1 */ (([id] = 1 /* @2 */) , [user_id] null)
so it's correct, i'd expect see [discriminator] = 'concretetwo'
in update statement. expectations unfounded or doing wrong?
as test, tried using table-per-type , the entry removed concreteone
table , added concretetwo
table expect. works, real application has @ least 7 sub-types , sql statement retrieve base
property got nasty. i'd accomplish using tph, if possible.
update: i've verified problem exists in ef5 ef6.
this question based on expectation of update taking place, seemingly debatable expectation. best bet if tph hierarchy not functioning expected, , considering ef6 in beta, start discussion on codeplex forums.
Comments
Post a Comment