using (var ctx = new Model.VMcontext())
{
List<Model.Process> Pr = new List<Model.Process>();
Model.Process pp;
foreach (RemoteProcess item in queueItem.rp)
{
pp = new Model.Process(item.ProcName, item.Procstatus, item.Timestamp, item.mcName);
Pr.Add(pp);
}
VM vm = new VM(queueItem.VM_Hostname, queueItem.Disks ,queueItem.VMstatus, Pr);
// compare vm object ref with current db objects
// If VM not present, insert VM
VM DBvm = ctx.VirtualMachines.Find(vm.VM_Hostname);
if (DBvm==null)
{
ctx.VirtualMachines.Add(vm);
}
// else VM exists so, update it [ERROR OCCURS HERE]
else
{
//DBvm = vm;
//ctx.Entry(vm).State = EntityState.Modified; I tried various update methods too
DBvm.disks = vm.disks;
DBvm.Processes = vm.Processes;
DBvm.VMstatus = vm.VMstatus;
}
ctx.SaveChanges();
}
当我更新现有记录时,会抛出异常。我在这里查找了其他答案,但似乎没有任何帮助。
类型&#39; System.Data.Entity.Infrastructure.DbUpdateException&#39;的例外情况发生在EntityFramework.dll中但未在用户代码中处理
其他信息:更新条目时发生错误。有关详细信息,请参阅内部异常。
哪里出错了?
修改 正如所建议的那样,查看内部异常,它说我试图插入一个重复的值&#39; C:&#39;进入磁盘表。但我没有插入任何数据,我只是找到现有的记录并更新它。我不确定如何获得主键重复错误*
编辑2
public class VM
{
public VM(string host,List<Disk>d ,int stat,List<Process> procs)
{
VM_Hostname = host;
disks = d;
VMstatus = stat;
Processes = procs;
}
public VM() { }
[Key]
public string VM_Hostname { get; set; }
public int VMstatus { get; set; }
public virtual ICollection<Model.Process> Processes { get; set; }
public virtual List<Disk> disks { get; set; }
}
public class Process
{
public Process(string pname,int stat,DateTime d, string vm )
{
ProcessName = pname;
status = stat;
date = d;
VM_hostname = vm;
}
public Process() { }
[Key]
public string ProcessName { get; set; }
public int status { get; set; }
public DateTime date { get; set; }
public string VM_hostname { get; set; }
[ForeignKey("VM_hostname")]
public virtual Model.VM vm { get; set; }
}
public class Disk
{
[Key]
public string name { get; set; }
public double freeSpace { get; set; }
public double freePercent { get; set; }
public double totalSpace { get; set; }
public double used { get; set; }
public string VM_hostname { get; set; }
[ForeignKey("VM_hostname")]
public virtual Model.VM vm { get; set; }
}
答案 0 :(得分:0)
正如我在评论中提到的,您的问题是您正在使用在创建当前上下文之前创建的Disk
和Process
对象的列表。因此,上下文不知道它们,当您替换Disk
实体上的Process
和VM
对象列表时,上下文假定它们都是新项目,并尝试将它们添加到数据库中。但由于它们不是新项目,因此存在导致您看到异常的主要冲突。
要解决您的问题,您需要在保存之前将Disk
和Process
个对象附加到您的上下文中。
E.g:
VM DBvm = ctx.VirtualMachines.Find(vm.VM_Hostname);
if (DBvm==null)
{
ctx.VirtualMachines.Add(vm);
}
// else VM exists so, update it [ERROR OCCURS HERE]
else
{
//DBvm = vm;
//ctx.Entry(vm).State = EntityState.Modified; I tried various update methods too
foreach (var disk in vm.disks)
{
//Only attach if the entity already exists, otherwise just let it get added.
if (ctx.Disks.Find(disk) != null)
{
ctx.Disks.Attach(disk);
ctx.Entry(disk).State = EntityState.Modified;
}
}
foreach (var process in vm.Processes)
{
if (ctx.Processes.Find(process) != null)
{
ctx.Processes.Attach(process);
ctx.Entry(process).State = EntityState.Modified;
}
}
DBvm.disks = vm.disks;
DBvm.Processes = vm.Processes;
DBvm.VMstatus = vm.VMstatus;
}
添加用于附加实体的循环应解决异常,因为它告诉上下文有关这些对象,并将其状态设置为已修改意味着它们不是新的,应该更新,而不是插入。