我正在使用EF6进行代码优先迁移来创建我的数据库。我的模型犯了一个错误,但我很难理解为什么会发生这种情况。
我有两张桌子
[TrackChanges]
public class Loan
{
public long Id { get; set; }
....
public virtual LoanAddress LoanAddress { get; set; }
public Loan() {
LoanAddress = new LoanAddress();
}
}
[TrackChanges]
public class LoanAddress
{
public long Id { get; set; }
...
}
当我使用新的LoanAddress创建新的贷款时,它通常会创建两个LoanAddresses。一个被分配给贷款,另一个是孤儿。
public async Task<IHttpActionResult> Create(LoanViewModel l)
{
try
{
Loan loan = new Loan
{
//LoanAddress = new LoanAddress(),
...
};
dbContext.Loan.Add(loan);
await dbContext.SaveChangesAsync(currentUserName);
return Ok(loan.Id);
}
catch (Exception ex)
{
....
}
}
如果我调试并逐步执行,dbContext.LoanAddress在Local中有两个条目。
让我感到困惑的是,当
时,这种情况不会发生没有帮助的一件事是LoanAddress没有引用贷款。这是一个错误(这对一个没有?),但使用代码优先迁移很难解决它。我在表格中有实时数据,我不确定是否可以解决这个问题。
否则,创建和更新工作,只是创建贷款创建孤立的行。
答案 0 :(得分:0)
首先,永远不要在实体构造函数中初始化引用导航属性。 Here我已经解释了为什么不。
这有点令人惊讶,这也会导致创建孤立LoanAddress
,因为在您的代码中,默认实例(来自构造函数)永远不会附加到更改跟踪器,因为它被替换为添加Loan
之前的新实例。当您更新现有的Loan
时,可能会发生这种情况。
其次,如果你Add
一个实体,属于它的所有实体也被标记为Added
(如果它们尚未附加到上下文中)。我假设你实际上打算在这里有一个新的LoanAddress
,所以这应该没问题。