我有一个方法接受带有添加或更新记录的事务列表的输入参数。
我遍历列表以发现修改了哪个并使用以下方法添加了whish: context.Entry(item).State = System.Data.EntityState.Modified; 设置每笔交易的状态。
我遇到的问题是因为事务对象与TransactionType有关系,而我遍历事务的输入参数列表,如果在数据库中有多个具有相同事务ID的事务,则会出现以下错误:< / p>
ObjectStateManager中已存在具有相同键的对象。 ObjectStateManager无法跟踪具有相同对象的多个对象 键。
关注的方法是:
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;
}
答案 0 :(得分:1)
我的问题的解决方案是将添加与更新分开。对于更新,从数据库中获取每一行,使用新值设置原始值。对于add,只需将新值添加到上下文中。
foreach (var item in transactions)
{
if (item.TransactionId > 0) //Update
{
var original = context.Transaction.Where(
t => t.TransactionId == item.TransactionId)
.FirstOrDefault();
original.TransactionType = context.TypeTransaction.Single(
p => p.TypeTransactionId == item.TransactionType.TypeTransactionId);
context.Entry(original).CurrentValues.SetValues(item);
}
else //Insert
{
item.TransactionType = context.TypeTransaction.Single(
p => p.TypeTransactionId == item.TransactionType.TypeTransactionId);
context.Transaction.Add(item);
}
}
context.SaveChanges();
答案 1 :(得分:0)
解决此问题的另一种方法:
foreach (var item in updated)
{
var original = db.MyEntities.Find(item.Id);
db.Entry(original).CurrentValues.SetValues(item);
}
db.SaveChanges();