entity framework - AddOrUpdate throws "A foreign key value cannot be inserted" with one to many relationship -


my application targets .net 4.5 , uses entityframework 5.0, sql server compact 4.0.

i'm trying seed database entities, keeps throwing:

"system.data.sqlserverce.sqlceexception: foreign key value cannot inserted because corresponding primary key value not exist. [ foreign key constraint name = fk_dbo.user_dbo.account_accountkey ]"

here simplified version of domain 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 here sample application shows issue:

class program {     static void main(string[] args)     {         try         {             database.setinitializer(new dropcreatedatabaseifmodelchanges<testcontext>());             using (var context = new testcontext())                 context.database.initialize(false);              (int = 0; < 2; i++ )                 using (var context = new testcontext())                 {                     var account1 = new account()                     {                         name = "account1"                     };                      var user1 = new user()                     {                         name = "user1",                         account = account1                     };                      context.accounts.addorupdate(                         e => e.name,                         account1                     );                      context.users.addorupdate(                         e => e.name,                         user1                     );                      context.savechanges();                      console.writeline("\nchanges saved.");                 }         }         catch (exception e)         {             console.writeline(e.tostring());         }          console.writeline("\npress key exit...");         console.readline();     } } 

the account class has 1 many relationship user class. seed method tries initialize default account default user. 1 think common usage of addorupdate method, not seem work in case. if add same account twice, no user, works no problems.

does can see point missing?

is there wrong in simple relationship?

is addorupdate method designed work in situations this?

if not, correct approach accomplish kind of seeding?

this should on track:

using (var context = new testcontext()) {     // 1:many don't need specify pk when seeding, ef pick     var accounts = new list<account>     {         // new list of type user each account         new account() { name = "account1", users = new list<user>() },         new account() { name = "account2", users = new list<user>() }     };     accounts.foreach(a => context.accounts.addorupdate(a));     context.savechanges();      var users = new list<user>     {         // set account key each user         new user() { name = "user1", accountkey = 1 },         new user() { name = "user2", accountkey = 1 },         new user() { name = "user3", accountkey = 2 },         new user() { name = "user4", accountkey = 2 }     };     users.foreach(u => context.users.addorupdate(u));     context.savechanges();      // add users list of type user in account     accounts[0].users.add(users[0]);     accounts[0].users.add(users[1]);     accounts[1].users.add(users[2]);     accounts[1].users.add(users[3]);     context.savechanges(); } 

edit

you'd want drop , recreate database before doing this, because if seeded database several times , "add same account twice, no user", there number of rows in account table , none in user table.

you add following annotation user.account:

[foreignkey("accountkey")] public account account { get; set; } 

also, what's reason none of navigation properties virtual?


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -