EF Вставляет уже существующий элемент - PullRequest
0 голосов
/ 06 марта 2012

Сначала я использую код EF 4.1 для веб-сайта, над которым я работаю.Нет, у меня небольшая проблема: EF пытается вставить элемент, который уже находится в базе данных, и который уже загружен из базы данных через EF.

Таким образом, я действительно вижу, что Элемент существует в контексте, но дляпо какой-то причине он снова добавляет клуб и помечает его как добавленный в контекст.Вот что я делаю.

У меня есть 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(); 
}

Это в моем базовом классе репозитория, это get 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);

Вот код в моих пользовательских службах, пока что мало что делает ...

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

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

А вот код в репозитории user, который добавляет нового пользователя.

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

С уважением, Магнус

1 Ответ

0 голосов
/ 06 марта 2012

Если вы используете шаблон репозитория, то вам нужно отсоединить Клуб, который вы добавляете, от Репозитория Клубов и прикрепить его к Репозиторию пользователей.Если вы этого не сделаете, то EF пометит клуб как добавленную сущность к контексту и попытается сохранить информацию, которая у вас уже есть, для сущности, для которой вы, скорее всего, определите Первичный ключ, нарушив тем самымПервичный ключ противопоказан.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...