c# - EF - Remove a relationship from parent entity -


let's have 2 classes in model: product , category.

public class product {     public product() {         this.categories = new hashset<category>();     }      [...]      public virtual icollection<category> categories { get; set; } }  public class category {     public category() {         this.products = new hashset<product>();     }      [...]      public virtual icollection<product> products { get; set; } } 

a product has many categories , categories apply many products. model relationship have following code in onmodelcreating method:

    modelbuilder.entity<product>()         .hasmany( p => p.categories )         .withmany( p => p.products )         .map( m => {             m.mapleftkey( "productid" );             m.maprightkey( "categoryid" );             m.totable( "categoriesperproduct" );         } );     modelbuilder.entity<category>()         .hasmany( p => p.products )         .withmany( p => p.categories )         .map( m => {             m.mapleftkey( "categoryid" );             m.maprightkey( "productid" );             m.totable( "categoriesperproduct" );         } ); 

this create new table, categoriesperproduct, splits m-n relationship in 2 1-n relationships needs.

i have requirement update categories related product and, simplify code, did decided remove existing categories , adding new ones in following sample:

icollection<category> productcategories = product.categories; //first remove existing categories  foreach ( var category in productcategories ) {     product.categories.remove( category ); } // ..then add new ones input foreach ( string categoryname in categories ) {     category c = await _ctx.categories.singleordefaultasync( p => p.description == categoryname );     if ( c != null ) {         product.categories.add( pc );     }     else {         c = new productcategory() { description = categoryname };         _ctx.categories.add( c );         await _ctx.savechangesasync();         product.categories.add( c );     } } await _ctx.savechangesasync(); 

unfortunately, when code hits transaction commit() method following error:

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.

could drive me in right direction solve error?

edited once more

something else occurred me may orphaning other side of relationship -- you're removing category entity product, removing product category? willcascadeondelete (entity framework (ef) code first cascade delete one-to-zero-or-one relationship) or try including relationships in queries -- instead of _ctx.products.where(...), use _ctx.products.include(p => p.categories).where(...)

let know how works out you!

edited

so, based on lorenzo's response, understand he's trying do. that's bit me (and few people) in past.

you're looking @ cascade delete problem -- go option 3 (which not option requirement...).


take @ the relationship not changed because 1 or more of foreign-key properties non-nullable

the main issue (as far can tell since don't know schema of categoriesperproduct: our perpetrator): you're putting entry categoriesperproduct in impossible state requires category exist, category has been set null.

therefore, have few options:

  1. make foreign key nullable (not recommended)
  2. remove item directly dbcontext (something _ctx.categories.remove(category);)
  3. mark state deleted (something ctx.entry(category).state = entitystate.deleted)

Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -