entity framework 4 - EF6 Update Attach Needs IsModified else Silent Fail vs EF4 -


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();     } 
  1. 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