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:
- make foreign key nullable (not recommended)
- remove item directly dbcontext (something _ctx.categories.remove(category);)
- mark state deleted (something ctx.entry(category).state = entitystate.deleted)
Comments
Post a Comment