2012-03-06 32 views
0

我正在使用EF 4.1代碼首先爲我工作的網站。不,我有一個小問題,即EF嘗試插入已經在數據庫中並且已經從數據庫通過EF加載的項目。EF插入已有項目

所以我實際上可以看到Item存在於上下文中,但由於某種原因,它再次添​​加了俱樂部並將其標記爲已添加到上下文中。這是我正在做的。

我有2個實體。俱樂部和用戶與實體之間存在着多對多的關係。所以俱樂部可以有很多用戶,用戶可以屬於很多俱樂部。

  • 因此,我通過EF從數據庫加載俱樂部。
  • 然後,我創建一個新的用戶,並將俱樂部添加到我的屬性俱樂部用戶類。
  • 然後我嘗試通過EF保存用戶。

這裏我得到一個關於違反俱樂部主鍵的例外。所以它試圖將俱樂部插入到數據庫中,當它所要做的就是將俱樂部標識符和用戶標識符添加到我的Club_User關係表中,並且當然保存用戶...並且

爲什麼上下文認爲它是新的當俱樂部已經存在於上下文中時,應該加入俱樂部嗎?

下面是代碼關於俱樂部和用戶

首先,我創建的EntityContext並將其添加到HttpContext.Current.Item

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
    //-- Create an instance of EntityContext 
    HttpContext.Current.Items[Constants.ENTITYCONTEXT] = new EntityContext(); 
} 
protected void Application_EndRequest(Object sender, EventArgs e) 
{ 
    //-- Clean up the entitycontext 
    var entityContext = HttpContext.Current.Items[Constants.ENTITYCONTEXT] as EntityContext; 
    if (entityContext != null) 
     entityContext.Dispose(); 
} 

這是在我的庫基類,這得到的的的EntityContext HttpContext的。

//-- EntityContext 
private EntityContext CurrentContext 
{ 
    get { return HttpContext.Current.Items[Constants.ENTITYCONTEXT] as EntityContext; } 
} 

在這裏我得到了我將要使用的俱樂部。

private Domain.Model.Club LoadClubByIdentifier(Guid identifier) 
{ 
    return this.CurrentContext.Clubs.SingleOrDefault(c => c.Identifier == identifier); 
} 

這是我的控制器類中創建用戶的一些代碼。

Domain.Model.User user = Mapper.Map<Web.Content.Code.Models.User.CreatePlayer, Domain.Model.User>(model); 
user.Identifier = new Guid().NewSequentialGuid(); 

//-- Get current club 
user.Clubs.Add(base.CurrentClub); 

//-- Get all teams and add them to user 
foreach (string teamIdentifier in model.Team) 
{ 
    Domain.Model.Team team = new Domain.Services.TeamServices().LoadByIdentifier(
     Domain.Helper.CryptationHelper.DecryptIdentifier(teamIdentifier)); 

    user.Teams.Add(new TeamUser() { Team = team, User = user, UserTeamRelation = UserTeamRelationEnum.Player }); 
} 

//-- Create this user 
new Domain.Services.UserServices().CreatePlayer(user); 

這裏是我的userServices代碼,並沒有做太多尚未...

public void CreatePlayer(Domain.Model.User user) 
{ 
    Password password = Password.GenerateRandomPassword(); 
    user.Password = password; 

    //-- Save the user to storage 
    _userRepository.SaveUser(user); 
} 

這裏是在增加新用戶的userRepository的代碼。

//-- Methods 
private void SaveUser(Domain.Model.User user) 
{ 
    this.CurrentContext.Users.Add(user); 
    this.CurrentContext.SaveChanges(); 
} 

問候 馬格努斯

回答

0

如果您正在使用的存儲庫模式,那麼你必須分離你是從俱樂部庫加入俱樂部,並將其安裝到用戶系統信息庫。如果您不這樣做,那麼EF會將俱樂部標記爲上下文的附加實體,並嘗試保存您已經擁有的實體信息,而這些信息很可能會定義主鍵,從而違反了主鍵約束。

+0

嗨。我不確定我是否使用存儲庫模式。我有一個EntityContext存儲在HttpContext.Current.Item中,所以它應該是通過整個請求相同的EntityContext。所以當我加載俱樂部並保存用戶時,它就是我使用的同一個Entitycontext對象。 – 2012-03-06 11:59:21

+0

您可以發佈從上下文中獲取俱樂部和用戶的代碼,直到您保存用戶。 – bdparrish 2012-03-06 12:01:36

+0

嗨。我必須這樣做,我現在無法訪問代碼。但是如果我記得正確的(在閱讀關於存儲庫patten之後),我使用這種模式,但是我沒有爲每個存儲庫創建一個新的上下文,而是使用存儲在Application_BeginRequest中設置的HttpContext.Current.Item中的自己)並放置在Application_EndRequest()中。 – 2012-03-06 12:13:19