2017-03-13 13 views
0
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(); 
     } 

既存のレコードを更新すると、例外がスローされます。私はここで他の答えを見上げたが、誰も助けてくれないようだ。既存のレコードを更新しようとしたときのDbUpdateException

型「System.Data.Entity.Infrastructure.DbUpdateException」の例外がEntityFramework.dllで発生したが、ユーザーコードで

追加情報を扱っていなかった。エントリを更新中にエラーが発生しました。詳細については、内部例外を参照してください。

どこが間違っていますか?

編集 としては、提案内部例外に見て、それは私が重複する値を挿入しようとしていると言う「C:」をディスクテーブルに。しかし、私は、既存のレコードを見つけて更新するだけで、データを挿入しているわけではありません。イムではないイムは、主キーの重複エラーを取得する方法を確認してください*

EDIT 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

内の例外に移動し、メッセージが何であるかを確認してください。 – Rinktacular

+0

System.Data.SqlClient.SqlException:PRIMARY KEY制約 'PK_dbo.Disks'の違反。オブジェクト 'dbo.Disks'に重複キーを挿入できません。重複するキー値は(C:\)です。 – NeuralLynx

+0

@Rinktacularしかし、重複するレコードを挿入していないのですが、ただ更新していますか? – NeuralLynx

答えて

0

私は私のコメントで述べたように、あなたの問題は、あなたがたDiskProcessオブジェクトのリストを使用していることです現在のコンテキストが作成される前に作成されます。したがって、コンテキストはそれらについて認識しておらず、​​エンティティのDiskおよびProcessオブジェクトのリストを置き換えると、コンテキストはすべて新しいアイテムであるとみなされ、それらをデータベースに追加しようとします。しかし、新しい項目ではないので、あなたが見ている例外を引き起こす主キーの競合があります。

問題を解決するには、保存する前にDiskProcessオブジェクトをコンテキストに追加する必要があります。

例:

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; 

} 

それは、彼らは新しいものではありません変更手段に自分の状態を設定し、これらのオブジェクトについてのコンテキストを伝え、以降、例外を解決する必要がありますあなたのエンティティをアタッチするループの追加、およびべき挿入されるのではなく、更新される。

関連する問題