EF SaveChanges () генерирует исключение «Свойство EntityKey может быть установлено только в том случае, если текущее значение свойства равно нулю» - PullRequest
2 голосов
/ 05 июля 2011

Я читал все похожие посты, которые я нашел относительно EF, но мне все еще не удается найти решение.

Я очень новичок в EF, и я читал некоторую полезную информацию о работес этим, но я думаю, что я что-то упускаю.

Сценарий таков:

Я хочу, чтобы пользователь мог создать учетную запись на веб-странице ASP.NET.Итак, у меня есть таблица с именем «Счета».Пользователь должен согласиться с условиями условий сайта, которые могут быть обновлены в будущем, поэтому у меня также есть таблица с именем ConditionTerms, которая имеет отношение «1 ко многим» с учетной записью (многие учетные записи имеют уникальный термин условия).

Я хотел отделить определенные личные данные пользователя от данных учетной записи, поэтому я также создал таблицу под названием «Персоны» и настроил связь, чтобы у человека было много учетных записей.

Теперь, когда я хочу сохранить учетную запись в базе данных, я извлекаю последний условие условия, доступный в базе данных, и присоединяю его к сущности учетной записи.Затем, когда я пытаюсь сохранить данные с помощью SaveChanges (), я получаю исключение, упомянутое в заголовке поста.Дело в том, что если все сущности являются новыми, то при создании ассоциаций EntityState для всех элементов «Отдельно», и он работает, но когда я извлекаю существующий conditionTerm из базы данных и добавляю его в account.ConditionTermучетная запись меняет свое состояние на «Добавлено», а затем выдает исключение.

Я где-то читал, что когда это происходит, это означает, что все дерево сущностей считается уже добавленным контекстом, и я должен тольконеобходимо вызвать SaveChanges () без метода AddObject (), поскольку он уже добавлен.Я попробовал это, и тогда я не получаю никаких исключений, и код заканчивается, но затем, если я проверяю базу данных (SQL Server 2008 express), учетная запись вообще не добавляется.

Это код, который япытается, и я думаю, что это должно работать, но ясно, что я что-то упускаю:

[TestMethod]
public void TestCreateNewAccount()
{
    try
    {
        AccountRepository accountRepository = new AccountRepository();

        Account account = new Account()
        {
            Username = "TestUsername",
            Password = "TestPassword",
            Email = "TestEmail",
            Nickname = "TestNickName",
            Quote = "Test Quote",
            AgreedToTermsDate = DateTime.Now,
            CreationDate = DateTime.Now,
            LastUpdateTime = DateTime.Now
        };

        // This works (all new entities!)
        //ConditionTerm conditionTerm = new ConditionTerm()
        //{
        //    Text = "This is some test condition term.",
        //    CreationDate = DateTime.Now,
        //    LastUpdateTime = DateTime.Now
        //};

        //This does not work (attaching an existing entity to a new one)
        ConditionTerm conditionTerm = new ConditionTermsRepository().GetCurrentTerm();

        Person person = new Person()
        {
            FirstName = "TestName",
            Surname = "TestSurname",
            CreationDate = DateTime.Now,
            LastUpdateTime = DateTime.Now
        };

        account.ConditionTerm = conditionTerm;
        account.Person = person;   

        using (ImproveEntities entities = Connection.GetModel())
        {
            if (account.ID > 0)
            {
                Account newAccount = new Account();
                newAccount.ID = account.ID;
                entities.Accounts.Attach(newAccount);
                entities.Accounts.ApplyCurrentValues(account);
            }

            else
            {
                entities.Accounts.AddObject(account);
                entities.SaveChanges();
            }
        }
    }

    catch (Exception)
    { 
    }
}

Любая помощь будет очень ценится!

РЕДАКТИРОВАТЬ: Этометод GetCurrentTerm ():

    public ConditionTerm GetCurrentTerm()
    {
        using (ImproveEntities entities = Connection.GetModel())
        {
            ConditionTerm conditionTerm = (from ct in entities.ConditionTerms
                                           orderby ct.CreationDate descending
                                           select ct).FirstOrDefault();
            return conditionTerm;
        }
    }

1 Ответ

4 голосов
/ 06 июля 2011

Если я правильно понимаю, вы хотите вставить новую учетную запись вместе с новым пользователем в базу данных. Но вы не хотите создавать новый ConditionTerm, а вместо этого назначаете существующий ConditionTerm учетной записи.

Проблема в том, что вы выбираете существующий ConditionTerm в другом контексте (в вашем GetCurrentTerm), чем тот, который вы используете для сохранения новой учетной записи. Этот второй контекст ничего не знает о ConditionTerm, поэтому вы должны EF точно сказать, что этот условие условия уже существует, подключив его ко второму контексту:

    // ...
    using (ImproveEntities entities = Connection.GetModel())
    {
        entities.ConditionTerms.Attach(conditionTerm);

        account.ConditionTerm = conditionTerm;
        account.Person = person;   

        entities.Accounts.AddObject(account);
        entities.SaveChanges();
    }
    // ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...