EF插入已存在的项目

时间:2012-03-06 11:12:55

标签: entity-framework-4

我首先在我工作的网站上使用EF 4.1 Code。不,我有一个小问题,EF尝试插入已经在数据库中的项目,并且已经从数据库通过EF加载。

所以我实际上可以看到项目存在于上下文中,但由于某种原因,它再次添​​加了俱乐部并将其标记为添加到上下文中。这就是我在做的事情。

我有2个实体。俱乐部和用户与实体之间存在多对多关系。因此,俱乐部可以拥有许多用户,用户可以属于许多俱乐部。

  • 所以我从数据库通过EF加载俱乐部。
  • 然后我创建了一个新用户,并将该俱乐部添加到我的用户类别的俱乐部。
  • 然后我尝试通过EF保存用户。

这里我得到一个关于违反Club主键的例外情况。所以它尝试将俱乐部插入到数据库中时应该做的就是将clubidentifier和useridentifier添加到我的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(); 
}

这是在我的Repository基类中,这是来自HttpContext的entityContext。

//-- 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);
}

以下是我的controllerclass中创建用户的一些代码。

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();
}

祝你好运 马格努斯

1 个答案:

答案 0 :(得分:0)

如果您使用的是存储库模式,则必须从俱乐部存储库中分离要添加的俱乐部并将其附加到用户存储库。如果您不这样做,那么EF会将俱乐部标记为上下文的附加实体,并尝试保存您已经拥有的实体信息,您很可能会定义主键,从而违反了主键约束。