更新时出现奇怪的错误 [英] Strange error on Updating
问题描述
各位大家好!
首先抱歉我的英语不好。
我是一名初学程序员,我有以下问题。
使用EF和通用存储库,我可以进行插入和删除问题。
当我对同一个数据库和同一个对象进行更新时调用此问题。
错误信息如下:
System.InvalidOperationException
收藏被修改;枚举操作可能无法执行。
我做了一些研究,但我无法解决问题是什么......
奇怪的是我使用与select /或insert相同的上下文(因此集合必须相同)。
有人有想法吗?
非常感谢提前!
代码:
这是通用存储库中的方法
Hello everybody!
First of all sorry about my bad English.
I am a starting programmer and I have following problem.
With EF and a generic repository I can do an Insert and Delete without any problem.
The problem is invoked when I do an update on the same database and same object.
The error message is the following:
System.InvalidOperationException
Collection was modified; enumeration operation may not execute.
I have done some research but I can't solve of figuring out what is the problem...
The strange thing is that I use the same context as the select / or insert (so the collection must be the same).
Has anyone an idea?
Many thanks in advance!
the code:
this is the method in the generic repository
public static T AddOrUpdate<T>(this DbContext context, T entity)
where T : class
{
if (context == null) throw new ArgumentNullException("context");
if (entity == null) throw new ArgumentNullException("entity");
if (IsTransient(context, entity))
{
context.Set<T>().Add(entity);
}
else
{
context.Set<T>().Attach(entity); //here I get the error
context.Entry(entity).State = EntityState.Modified;
}
return entity;
}
这是我的伤害核心
This is my damagecore
public static Result NewDamage(Context ctx, CarDamage _newCarDamage)//Damage _newDamage)
{
GenericRepository<CarDamage> carCamageRepo = new GenericRepository<CarDamage>(ctx);
carCamageRepo.AddOrUpdate(_newCarDamage);
ctx.SaveChanges();
return null;
}
按钮背后的代码
code behind the button
private void save_Click(object sender, RoutedEventArgs e)
{
double invAmount;
if (NoEmptyFieldsCheck() == false)
{
MessageBox.Show("Gelieve alle velden in te vullen", "Schade", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (DamageOverviewCheck() == false)
{
MessageBox.Show("Gelieve minstens 1 schade onderdeel toe te voegen", "Schade", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (Double.TryParse(invoiceAmount.Text, out invAmount)== false)
{
MessageBox.Show("Geef een geldig factuurbedrag","Schade", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// Damage newDamage = new Damage();
// CarDamage newCarDamage = new CarDamage() { Car = (Car)carComboBox.SelectedItem, ActualValue= true };
carDamage.Car = (Car)carComboBox.SelectedItem;
carDamage.ActualValue = true;
newDamage.DamageDate = damageDate.SelectedDate ?? DateTime.Today;
newDamage.DamageState = (DamageState)damageStateComboBox.SelectedItem;
newDamage.DamageCauser = damageCauser.Text;
newDamage.InvoiceAmount = (float)invAmount;
newDamage.PaymentFranchiseDriver = paymentFranchiseDriver.IsChecked.Value;
newDamage.PaymentOk = paymentOk.IsChecked.Value;
newDamage.DamageOverview = damageOverview;
if (accident.IsChecked == true)
{
Accident newAccident = new Accident();
newAccident.AccidentFileDate = fileDate.SelectedDate ?? DateTime.Today;
newAccident.FileState = (FileState)fileStateComboBox.SelectedItem;
newAccident.AccidentDescription = accidentDescriptionTxtBox.Text;
newDamage.Accident = newAccident;
}
if (files.Count > 0)
{
foreach (var file in files)
{
Document doc = new Document();
string fileExtention = Path.GetExtension(file);
string fileName = Path.GetFileNameWithoutExtension(file);
string originalFilePath = Path.GetFullPath(file);
doc.FileDestination = @"C:\Users\Jeffry\Desktop\document.carma\" + doc.DocumentID + fileExtention;
doc.OriginalFileName = fileName;
doc.AdditionDate = DateTime.Today;
File.Copy(originalFilePath, doc.FileDestination);
}
newDamage.Document = docList;
}
carDamage.CarID = (int)carComboBox.SelectedValue;
carDamage.ActualValue = true;
carDamage.Damage = newDamage;
DamageCore.NewDamage(mainWindow.ctx, carDamage);
id = newDamage.DamageID; //getting id of last added damage (needed to go to documents for getting right documents)
}
已添加15/04/2014
ObjectID传递给构造函数
Added 15/04/2014
ObjectID is passed to constructor
private void viewDetail_Click(object sender, RoutedEventArgs e)
{
CarDamage carDamage = (CarDamage)damageLV.SelectedItem;
DamagePage damagePage = new DamagePage(mainWindow, carDamage.DamageID);
mainWindow.MainFrame.Navigate(damagePage);
}
页面构造函数
Constructor of the page
public DamagePage(MainWindow main, int damageId)
{
mainWindow = main;
mainWindow.SetTitle("Detail schade");
InitializeComponent();
AddData();
carDamage = DamageCore.GetDamage(mainWindow.ctx, damageId);
//carDamage.CarDamageID = damageId;
FillDataOnForm(carDamage);
}
代码我获取CarDamage对象并填写表格...由构造函数调用
Code where i get CarDamage object and fill the form... is invoked by the constructor
private void FillDataOnForm(CarDamage carDamage)
{
damageDate.SelectedDate = carDamage.Damage.DamageDate;
carComboBox.SelectedValue = carDamage.CarID;
damageStateComboBox.SelectedValue = carDamage.Damage.DamageStateID;
damageCauser.Text = carDamage.Damage.DamageCauser;
invoiceAmount.Text = carDamage.Damage.InvoiceAmount.ToString("0.00");
paymentFranchiseDriver.IsChecked = carDamage.Damage.PaymentFranchiseDriver;
paymentOk.IsChecked = carDamage.Damage.PaymentOk;
accident.IsChecked = false;
if (carDamage.Damage.AccidentID != 0)
{
accident.IsChecked = true;
fileDate.SelectedDate = carDamage.Damage.Accident.AccidentFileDate;
fileStateComboBox.SelectedValue = carDamage.Damage.Accident.FileStateID;
accidentDescriptionTxtBox.Text = carDamage.Damage.Accident.AccidentDescription;
}
damageOverview = carDamage.Damage.DamageOverview;
damagesLV.ItemsSource = null;
damagesLV.ItemsSource = damageOverview;
docList = carDamage.Damage.Document;
id = carDamage.DamageID;
}
更新时间17/04/2014
通用更新
Update 17/04/2014
Generic update
public void Update(T entity)
{
var entry = _context.Entry(entity);
if (entry.State == EntityState.Detached)
{
_context.Set<T>().Attach(entity);
entry = _context.Entry(entity);
}
entry.State = EntityState.Modified;
}
update 23/04/2014
我仍然有同样的问题...
这是我的添加或更新方法......(也不起作用...... :()
update 23/04/2014
I still have the same problem...
Here is my add or update method... (which also doesn't work... :( )
public static T AddOrUpdate<T>(this DbContext context, T entity)
where T : class
{
if (context == null) throw new ArgumentNullException("context");
if (entity == null) throw new ArgumentNullException("entity");
if (IsTransient(context, entity))
{
context.Set<T>().Add(entity);
}
else
{
// original
context.Set<T>().Attach(entity);
// here i Get an error... and i don't know why...
//errormessage: Collection was modified; enumeration operation may not execute !!!!!!!!???????
context.Entry(entity).State = EntityState.Modified;
//test
//context.Entry<T>(entity).State = EntityState.Modified;
//context.Entry(entity).State = EntityState.Modified;
}
return entity;
}
推荐答案
1.在更新的情况下,实体必须具有其主键的有效值,所以EF可以在DB中找到它然后将它附加到当前上下文。
2.首先,你必须调试代码并检查在方法AddOrUpdate
的乞讨上面的第1点,如果来的数据不正确,你应该在调用的地方做更改!
3.你的carDemage
每次创建对象之前都要调用AddOrUpdate
您的save_Click
方法中的方法,如下一个代码:
1.In the case of update the entity must have valid value(s) for its "primary key", so the EF to can find it in the DB and then to attach it to the current context.
2.So first you have to debug your code and check the 1st point above at the begging of methodAddOrUpdate
, and if the data that come are not OK, you should do changes at the place of invocation!
3.YourcarDemage
object should be created each time before to invokeAddOrUpdate
method in yoursave_Click
method like in the next code:
CarDamage carDemage = new CarDemage();
carDemage.ID = ...; // must be set!
carDamage.ActualValue = ... // set the other properties!
//..
4.您正在尝试附加 CarDamage
对象 DbContext
对象,但该对象已附加到此EF上下文。因此解决方案是只搜索此对象(通过其ID),然后设置其更改的属性,最后 SaveChanges()
。
4.You are trying to attach an CarDamage
object to your DbContext
object, but the object is already attached to this EF context. So the solution is to just search for this object (by its ID), then set its changed properties, and finally SaveChanges()
.
这篇关于更新时出现奇怪的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!