【发布时间】:2013-02-09 11:35:46
【问题描述】:
我有一个方法接受一个输入参数,用于添加或更新记录的交易列表。
我循环遍历列表以发现哪些已修改并使用以下命令添加: context.Entry(item).State = System.Data.EntityState.Modified; 设置每个事务的状态。
我遇到的问题是因为事务对象与 TransactionType 有关系,而我循环遍历事务的输入参数列表,如果数据库中有多个具有相同事务 id 的事务,我会收到以下错误:
ObjectStateManager 中已存在具有相同键的对象。 ObjectStateManager 无法跟踪具有相同的多个对象 键。
- 顺便说一下,我使用的是 EF5 和 Code First。
关注的方法是:
public TransactionList SaveTransactions(Transaction[] transactions)
{
try
{
using (EntityContext context = new EntityContext())
{
foreach (var item in transactions)
{
if (item.TransactionId > 0)
context.Entry(item).State = System.Data.EntityState.Modified;
else
context.Entry(item).State = System.Data.EntityState.Added;
}
context.SaveChanges();
}
return GetLatestTransactions();
}
## 更新## 如果我将每个项目的 TransactionType 设置为 null,我不会收到任何错误,并且其余的事务字段将被很好地更新。即 TransAmount、Date 等。问题是通过将 TransType 设置为 null 我将永远无法更改我的交易类型。
using (EntityContext context = new EntityContext())
{
foreach (var item in transactions)
{
//set the fk to null
item.TransactionType = null;
if (item.TransactionId > 0)
{
context.Entry(item).State = System.Data.EntityState.Modified;
}
else
context.Entry(item).State = System.Data.EntityState.Added;
}
context.SaveChanges();
}
## 更新 2 ## 我刚刚找到了另一种可行的方法,但仍然不是我的理想选择。我得到每个项目的单笔交易,然后设置值。我不喜欢这个解决方案,因为 .Single 会为每次迭代做一次往返。
foreach (var item in transactions)
{
var or = context.Transaction
.Include(t => t.Category)
.Include(t => t.TransactionReasonType)
.Include(t => t.TransactionType)
.Single(t => t.TransactionId == item.TransactionId);
if (item.TransactionId > 0)
{
context.Entry(or).CurrentValues.SetValues(item);
context.Entry(or).State = System.Data.EntityState.Modified;
}
【问题讨论】:
-
如果来源有重复,你应该先解决这个问题。
-
复制只在外键上。即两个不同的事务可能具有相同的事务类型。我不会在我的参数或数据库中多次拥有相同的事务密钥。
标签: c# ef-code-first entity-framework-5