can please tell me why entity framework 6 needs "ismodified" line of code update attach, else code "silent fail" vs entity framework 4? in other words, in entity framework 4, update attach works. in ef6, if similar, db not update , no exception thrown (silent fail). if put "ismodified" line in code works, unacceptable, developers leave "ismodified" code out , updates fail, , nobody know.
this problem occur/not occur in ef6 under following conditions set in db: 1. if active set default 1 , allownulls=false, update fails 2. if active not set default , allownulls=false, update fails 3. if active not set default , allownulls=true, update works 4. if active set default 1 , allownulls=true, update works
this similar to: entityframework not saving null , false value not exact. walk through problem:
1) if have visual studio 2010, can follow along, else, can trust me ef4 works described.
in visual studio 2010, new project asp.net mvc 2 web application, using .net framework 4, , name ef4works. not create unit test.
2) sure add default , not allow nulls, important
create table [dbo].[document]( [id] [int] identity(1,1) not null, [documentname] [varchar](10) null, [active] [bit] not null constraint [df_document_active] default ((1)), constraint [pk_document] primary key clustered ( [id] asc )with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary] ) on [primary]
3) insert row "docname" 1(true)
4) add edmx table.
5) in home index controller (add controller if necessary) add , run code (similar) , check db works!(updates db) (put breakpoint before view called):
public actionresult index() { breazentities entities = new breazentities(); document document = new document { id = 1 }; entities.documents.attach(document); document.active = false; entities.savechanges(); return view(); }
6) put active flag 1
7) add new solution , project in visual studio 2013. web, .net framework 4.5.1 asp.net webapplication called ef6fails, next wizard page mvc, change authentication no authentication. in package manager console: uninstall-package entityframework -project ef6fails -force install-package entityframework -version 6.1.3 -project ef6fails
8) add edmx in ef6fails document table.
9) run code in controller , put breakpoint before view called:
public actionresult index() { breazentities6 entities = new breazentities6(); document document = new document { id = 1 }; entities.documents.attach(document); document.active = false; entities.savechanges(); return view(); }
this not working. have following, unacceptable because new developers exclude following , not know code not working. there something, can add globally solution not make developers add following? research , try add myself until answers so:
breazentities6 entities = new breazentities6(); document document = new document { id = 1 }; entities.documents.attach(document); /* following line needs added in ef6, not in ef4 */ entities.entry(document).property(e => e.active).ismodified = true; document.active = false; entities.savechanges(); return view();
you pointing out difference in code generation between ef 4.1 objectcontext
, ef 6 (4.1 , later, actually) dbcontext
.
in objectcontext
api, 1 single database field, active
, generate no less code this:
/// <summary> /// no metadata documentation available. /// </summary> [edmscalarpropertyattribute(entitykeyproperty=false, isnullable=false)] [datamemberattribute()] public global::system.boolean active { { return _active; } set { onactivechanging(value); reportpropertychanging("active"); _active = structuralobject.setvalidvalue(value); reportpropertychanged("active"); onactivechanged(); } } private global::system.boolean _active; partial void onactivechanging(global::system.boolean value); partial void onactivechanged();
meaning ef's change tracker informed of each property change.
the dbcontext
api wasn't change more developer-friendly api, simpler class model , move real persistence ignorance. believe in beginning, still self-tracking code generated, in end, abandoned , database field represented simple generated auto-property:
public bool active { get; set; }
(no doubt, done have 1 unified code base underlying code-first , database-first approaches).
inevitably, put more responsibility on shoulders of change tracker. had detect changes in stead of register them. reason, change-tracker method detectchanges
executed "al time".
back code.
in "old" objectcontext
api ...
document.active = false;
... inform change tracker property set. even when false, update
emitted on savechanges
.
in dbcontext
api, change tracker never detect change because active
has default value booleans, false
. nothing changes.
in short, used "what set update" , turned "what change update".
fine, what?
you want go had.
but you?
try change perspective bit. suppose you'd work code-first, write property code in first code fragment? really? one, tight coupling, no single-responsibility. , in disconnected scenario (i.e. reattaching deserialized entities) may lead many unnecessary updates.
however, if write (or generate) similar code, ef doesn't listen changes yet. you'd have subscribe materialized entities change-propagation code in context yourself. it's not built-in anymore, unless return objectcontext
api (which shouldn't want).
i'd say: live it. lose some, win lot (more solid code). used being in control of updated in database , isn't. may want set active
true default value in entity's constructor, change tracker notice change false
.
but don't think developers forgetting valid argument. developers supposed flexible. world changes time, not moving along not option. if can remember include ef-specific statementattach
(managing entity state), why not statements manage property state?
Comments
Post a Comment