entity framework - Delete parent with children in one to many relationship -


i have .net4.0 application entity framework 5.0 e sql server ce 4.0.

i have 2 entities 1 many (parent/child) relationship. i've configured cascade delete on parent removal, reason doesn't seem work.

here simplified version of entities:

    public class account     {         public int accountkey { get; set; }         public string name { get; set; }          public icollection<user> users { get; set; }     }      internal class accountmap : entitytypeconfiguration<account>     {         public accountmap()         {             this.haskey(e => e.accountkey);             this.property(e => e.accountkey).hasdatabasegeneratedoption(databasegeneratedoption.identity);             this.property(e => e.name).isrequired();         }     }       public class user     {         public int userkey { get; set; }         public string name { get; set; }          public account account { get; set; }         public int accountkey { get; set; }     }      internal class usermap : entitytypeconfiguration<user>     {         public usermap()         {             this.haskey(e => e.userkey);             this.property(e => e.userkey).hasdatabasegeneratedoption(databasegeneratedoption.identity);             this.property(e => e.name).isrequired();               this.hasrequired(e => e.account)                 .withmany(e => e.users)                 .hasforeignkey(e => e.accountkey);         }     }      public class testcontext : dbcontext     {         public testcontext()         {             this.configuration.lazyloadingenabled = false;         }          public dbset<user> users { get; set; }         public dbset<account> accounts { get; set; }          protected override void onmodelcreating(dbmodelbuilder modelbuilder)         {             modelbuilder.conventions.remove<pluralizingtablenameconvention>(); modelbuilder.conventions.remove<storegeneratedidentitykeyconvention>();             modelbuilder.loadconfigurations();         }      } 

the connection string:

  <connectionstrings>     <add name="testcontext" connectionstring="data source=|datadirectory|\testdb.sdf;" providername="system.data.sqlserverce.4.0" />   </connectionstrings> 

and simplified version of app's workflow:

static void main(string[] args) {     try     {         database.setinitializer(new dropcreatedatabasealways<testcontext>());         using (var context = new testcontext())             context.database.initialize(false);          account account = null;         using (var context = new testcontext())         {             var account1 = new account() { name = "account1^" };             var user1 = new user() { name = "user1", account = account1 };              context.accounts.add(account1);             context.users.add(user1);              context.savechanges();              account = account1;         }          using (var context = new testcontext())         {             context.entry(account).state = entitystate.deleted;                     context.savechanges();         }     }     catch (exception e)     {         console.writeline(e.tostring());     }      console.writeline("\npress key exit...");     console.readline(); } 

when try delete parent entity, throws:

the relationship not changed because 1 or more of foreign-key properties non-nullable. when change made relationship, related foreign-key property set null value. if foreign-key not support null values, new relationship must defined, foreign-key property must assigned non-null value, or unrelated object must deleted.

i believe relationship configuration ok (followed documentation). searched guidelines on deleting detached entities.

i cannot understand why delete won't work. want avoid loading children, deleting them 1 one , them deleting parent, because there must better solution that.

setting state of entity deleted , calling dbset<t>.remove entity not same.

the difference setting state changes state of root entity (the 1 pass context.entry) deleted not state of related entities while remove if relationship configured cascading delete.

if exception depends on children (all or part) being attached context or not. leads behaviour difficult follow:

  • if call remove don't exception, no matter if children loaded or not. there still difference:
    • if children attached context, ef generate delete statement every attached child, parent (because remove did mark them deleted)
    • if children not attached context ef send delete statement parent database , because cascading delete enabled database delete children well.
  • if set state of root entity deleted can possibly exception:
    • if children attached context state won't set deleted , ef complain trying delete principal (the root entity) in required relationship without deleting dependents (the children) or @ least without setting foreign keys root entity not in deleted state. that's exception had: account root , user1 dependent of account , calling context.entry(account).state = entitystate.deleted; attach user1 in state unchanged context (or change detection in savechanges it, i'm not sure abut that). user1 part of account.users collection because relationship fixup added collection in first context although didn't add explicitly in code.
    • if no children attached context setting state of root deleted send delete statement database , again cascading delete in database delete children well. works without exception. code work example if set account.users = null before setting state deleted in second context or before entering second context.

in opinion using remove...

using (var context = new testcontext()) {     context.accounts.attach(account);     context.accounts.remove(account);     context.savechanges(); } 

...is prefered way because behaviour of remove more expect required relationship cascading delete (which case in model). dependency of behaviour of manual state change on states of other entities makes more difficult use. consider advanced usage special cases.

the difference not known or documented. i've seen few posts it. 1 find right again, this 1 zeeshan hirani.


Comments

Popular posts from this blog

Change php variable from jquery value using ajax (same page) -

Pull out data related to my apps from Android Play Store and iOS App Store -

How can I fetch data from a web server in an android application? -