2016-04-28 1 views
0

私はEFを使ってデータベースに多くのデータを追加するプログラムを持っています。データの一つは、私はこの命令を持って、データベース内で一意である必要がありますレコードですので:EFで最初にクエリを実行し、見つからない場合はDBにクエリを実行する方法は?

DataWare.Funcionario funcionario = db.Funcionario.Where(f => f.FunRut.Equals(rut)).FirstOrDefault(); 

「funcionarioが」見つからない場合は、新しいオブジェクトが作成され、コンテキストにこのように追加されます。

db.Funcionario.Add(funcionario); 

これはforeach cicleの内側です。いくつかの反復では、同じ "funcionario"に遭遇すると、すでにコンテキストに追加されている場合でも、上記のWhereメソッドはnullを返します。

foreachの後で、私は文脈の変更を保存しています。

私は周囲を検索していましたが、そのメソッドが常にデータベースにクエリを実行し、ローカルプロパティを使用してコンテキスト内のオブジェクトをクエリできたことがわかりました。まず、ローカルインスタンスのみを常に照会するため、コンテキストで見つからない場合にデータベースを照会するために、2つの呼び出しを明示的に行う必要があります。 2番目の問題は、最悪の場合、SaveChangesをコンテキストに呼び出すと、同じレコードの多くの重複を保存することになります。どうしてか分かりません。ローカルとデータベースのデータが同期していないことが原因である可能性があります。

ご協力いただきますようお願い申し上げます。

おかげ ハイメ

EDIT:

これは、実際のシナリオです:私は実際に会社のスタッフのための時間の出席イベントの多くを保存するリスト<>を持っています。そのイベントは、時間出席者からのものです。

私が話していたforeachは、そのリストを通るforeachです。そのイベントとスタッフは、まだ存在しない場合に備えてデータベースに作成する必要があります。

スタッフが存在しない場合、システムは別のシステムへのリモートコールを実行してスタッフ情報を取得し、その情報を当社のシステムに保存します。スタッフが既に追加されている場合は、新しいインスタンスを作成する代わりにそのインスタンスを使用する必要があります。ところで、同じスタッフがその日にいくつかのイベントを生成することができます。だから私は自分のシステムに、発見されたスタッフまたは新しい作成されたスタッフを関連付けるイベントを追加します。

これはあなたの参照のためのforeachの完全なコードです:

 using (DataWare.SistemasBCIEntities db = new DataWare.SistemasBCIEntities()) 
     { 
      bool exito = false; 

      foreach (var log in logs.OrderBy(l => l.EnrollNumber)) 
      { 
       string rut = log.EnrollNumber.ToString(); 
       DataWare.Funcionario funcionario = db.Funcionario.Where(f => f.FunRut.Equals(rut)).FirstOrDefault(); 
       if (funcionario == null) 
        funcionario = GetPersonFromZKTime(rut, db); 

       if (funcionario != null) 
       { 
        // Si ya hay un evento para esa hora y ese funcionario, debe continuar con el siguiente 
        DataWare.Evento evento = db.Evento.Where(e => e.EveFechaHora.Equals(log.Date) && e.Funcionario.FunRut.Equals(rut)).FirstOrDefault(); 
        if (evento == null) 
        { 
         exito = true; 

         string tipoEvento = String.Empty; 
         if (log.InOutMode == DataWare.Terminal.InOutModeEnum.Check_In || log.InOutMode == DataWare.Terminal.InOutModeEnum.OT_In || log.InOutMode == DataWare.Terminal.InOutModeEnum.Break_In) 
          tipoEvento = "IN"; 
         else 
          tipoEvento = "OUT"; 
         evento = new DataWare.Evento() 
         { 
          Funcionario = funcionario, 
          EveFechaHora = log.Date, 
          EveTipo = tipoEvento, 
          EveFechaCreacion = DateTime.Now 
         }; 

         db.Evento.Add(evento); 
        } 
       } 
      } 

      db.SaveChanges(); 

      return exito; 
     } 

答えて

0

レコードを主キーにするために使用されるフィールドを変更した後、EFのFindメソッドを使用し、期待どおりに機能しました。

0

あなたはおそらくちょうどidは次のように実体の状態を設定してそれ以外の場合は設定されているかどうかを確認することができます

foreach(var rut in source.Distinct()) 
{  
    db.Entry(rut).State = rut.Id == 0 ? 
           EntityState.Added : 
           EntityState.Modified; 
} 
+0

レコードは常に追加されていますが、変更されていません。すでに追加されているレコードを取得するだけでした。 – jstuardo

関連する問題