我一直在阅读我发现的有关EF的所有类似帖子,但我仍然无法找到解决方案。
我是EF的新手,我一直在阅读一些有关使用它的有用信息,但我认为我错过了一些东西。
场景是这样的:
我希望用户能够在ASP.NET网页中创建帐户。所以我有一个名为'Accounts'的表。用户必须同意网站的条件条款,可以在futere中更新,因此我还有一个名为“ConditionTerms”的表,该表与帐户有1对多的关系(许多帐户都有唯一的条件术语)。 / p>
我想从帐户数据中分离出特定的个人用户数据,因此我还创建了一个名为“人员”的表格,并设置了关系,以便一个人拥有多个帐户。
现在,当我想将帐户保存到数据库中时,我检索数据库中可用的最后一个conditionTerm并将其附加到帐户实体。然后,当我尝试通过SaveChanges()保存数据时,我得到了帖子标题中提到的异常。问题是如果所有实体都是新的,当创建关联时,所有项的EntityState都是'Detached'并且它可以工作,但是当我从数据库中检索现有的conditionTerm并将其添加到account.ConditionTerm时,帐户将其状态更改为“已添加”,然后它会抛出异常。
我在某处读到,当发生这种情况时,它意味着所有实体树都被认为已经被上下文添加,我只需要在没有AddObject()方法的情况下调用SaveChanges(),因为它已经添加了。我尝试了这个,然后我没有异常,代码结束,但如果我检查数据库(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;
}
}
答案 0 :(得分:4)
如果我理解正确,您希望将新帐户与新用户一起插入数据库。但您不想创建新的ConditionTerm
,而是将现有的ConditionTerm
分配给该帐户。
问题是您在另一个上下文(在ConditionTerm
中)中获取现有GetCurrentTerm
,而不是用于保存新帐户的上下文。第二个上下文对ConditionTerm
一无所知,所以你必须通过将它附加到第二个上下文来明确告诉这个conditionTerm已存在:
// ...
using (ImproveEntities entities = Connection.GetModel())
{
entities.ConditionTerms.Attach(conditionTerm);
account.ConditionTerm = conditionTerm;
account.Person = person;
entities.Accounts.AddObject(account);
entities.SaveChanges();
}
// ...