Entity framework 4 EF插入已存在的项

Entity framework 4 EF插入已存在的项,entity-framework-4,Entity Framework 4,我正在使用EF4.1代码首先为一个网站,我的工作。不,我有一个小问题,EF尝试插入一个已经在数据库中的项,并且已经通过EF从数据库加载了该项 因此,我可以看到该项目确实存在于上下文中,但出于某种原因,它再次添加了俱乐部,并将其标记为已添加到上下文中。这就是我正在做的 我有两个实体。俱乐部和用户之间存在多对多关系。所以一个俱乐部可以有很多用户,一个用户可以属于很多俱乐部 所以我通过EF从数据库加载俱乐部 然后我创建一个新用户,并将该俱乐部添加到User类上的我的属性俱乐部中 然后我尝试通过EF保

我正在使用EF4.1代码首先为一个网站,我的工作。不,我有一个小问题,EF尝试插入一个已经在数据库中的项,并且已经通过EF从数据库加载了该项

因此,我可以看到该项目确实存在于上下文中,但出于某种原因,它再次添加了俱乐部,并将其标记为已添加到上下文中。这就是我正在做的

我有两个实体。俱乐部和用户之间存在多对多关系。所以一个俱乐部可以有很多用户,一个用户可以属于很多俱乐部

  • 所以我通过EF从数据库加载俱乐部
  • 然后我创建一个新用户,并将该俱乐部添加到User类上的我的属性俱乐部中
  • 然后我尝试通过EF保存用户
这里我得到一个关于违反俱乐部主键的例外。因此,它尝试将俱乐部插入数据库,而它所要做的只是将clubidentifier和useridentifier添加到我的club_用户关系表中,当然还要保存用户

为什么上下文认为应该添加一个新的俱乐部,而实际上俱乐部已经存在于上下文中

以下是关于俱乐部和用户的代码

首先,我创建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(); 
}
这是在我的存储库基类中,这是来自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);
下面是userRepository中添加新用户的代码

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

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

Hi。我不确定是否使用存储库模式。我在HttpContext.Current.Item中存储了一个EntityContext,因此在整个请求中它应该是相同的EntityContext。因此,当我加载俱乐部并保存用户时,它与我使用的Entitycontext对象是同一个对象。在保存用户之前,您能否发布从上下文获取俱乐部和用户的代码。嗨。我必须稍后再做我现在无法访问代码。但是,如果我记得正确的话(在阅读了关于存储库模式的内容之后),我会使用这个模式,但我不会为每个存储库创建新的上下文,而是使用存储在HttpContext.Current.Item中的自己的上下文,该上下文在应用程序_BeginRequest()中设置,并在应用程序_EndRequest()中处理。啊。。。没关系,我发现了问题。俱乐部在另一个申请中被添加到上下文中。如果我将EntityContext放在HttpContext.Current.Session中,它就会工作。但是,从性能的角度来看,这不是一件好事,是吗?使用依赖项解析器可以更好地抽象代码。这将允许您执行
public UserController(IUserRepository userRepo){{{u userRepository=userRepo;}
,然后执行
public void CreateUser(User User User){User existingUser=\u userRepository.Single(u=>u.Id==User.Id);}
//-- Methods
private void SaveUser(Domain.Model.User user)
{
    this.CurrentContext.Users.Add(user);
    this.CurrentContext.SaveChanges();
}