2017-02-08 3 views
0

私は今、すべての可能な方法でインターネットを検索していますが、答えが見つからなかったと思います。プロジェクト。だから私はここで解決策に満足しています。流暢なnハイバーネーションのジョインIDとヌル値

これは計画についてのものであり、図示のとおり、私は1週間中いつでも稼働するマシンを持っています。しかし、 "Nonproduction"テーブルには、生産ができないタイムスパン(estimatedStart - estimatedStop)があります。非生産レコードは、特定のマシン用である可能性がありますが、会社にとっても可能です。その場合、machineIDはnullになります。

だから、私が望むのは、すべてが非生産レコードであり、machineIdがnullの非生産レコードであるマシンを選択することです。

Diagram from MySQL

SQL文は非常に簡単になります!

select * from machine m 
left outer join nonproduction np on (m.machine_id = np.machineID or np.machineID is null) 
where m.machine_id=119; 

The select result from the above SQL

私の流暢なマシンマッピングはここに行く:(一部のコードはわかりやすくするために取り除かれている)、ここで

public class MachineMap : ClassMap<Machine> 
    { 
     public MachineMap() 
     { 
      Table("machine"); 
      Id(x => x.MachineId, "machine_id").GeneratedBy.Identity(); 
      Map(x => x.Name, "name"); 
      Map(x => x.Number, "machinenumber"); 
      Map(x => x.Size, "size"); 
      Map(x => x.Data1, "data1"); 
      Map(x => x.Data2, "data2"); 
      Map(x => x.Data3, "data3"); 

      HasMany(x => x.NonProductions) 
       .KeyColumn("machineID").KeyNullable() 
       .AsBag(); 

     } 
    } 

public class NonProductionMap : ClassMap<NonProduction> 
     { 
      public NonProductionMap() 
      { 
       Table("nonproduction"); 
       Id(x => x.NonproductionId, "Nonproduction_id").GeneratedBy.Identity(); 
       Map(x => x.NonproductionTypeId, "nonproduction_typeID"); 
       Map(x => x.MachineId, "machineID").Nullable(); 
       Map(x => x.WorkerId, "workerID"); 
       Map(x => x.EstimatedStart, "estimated_start"); 
       Map(x => x.EstimatedStop, "estimated_stop"); 
       Map(x => x.Visible, "nonproductionvisible"); 
       Map(x => x.Repetitiontime, "repetitiontime"); 

       References(x => x.Machine) 
        .Column("machineID") 
        .Not.Insert() 
        .Not.Update(); 
      } 
     } 

リポジトリコード:

public IEnumerable<Machine> GetMachinesForCalendar(int[] ids = null) 
    { 
     Machine m = null; 
     Order o = null; 
     NonProduction n = null; 

     var query = Session.QueryOver(() => m) 
      .JoinAlias(() => m.Orders,() => o, JoinType.LeftOuterJoin) 
      .JoinAlias(() => m.NonProductions,() => n, JoinType.LeftOuterJoin, Restrictions.Where(() => n.MachineId == m.MachineId || n.MachineId == null)); 

     if (ids != null && ids.Any()) 
     { 
      query = query 
       .WhereRestrictionOn(() => m.MachineId) 
       .IsIn(ids); 
     } 

     return query 
      .List() 
      .Distinct() 
      .ToList(); 

    } 

私がいることを知っています制限部分の "n.MachineId == m.MachineId"は暗黙のうちに記載されていますが、書くには、私は本当にここで素晴らしい解決策を見つけることができません。

データベースは非常に古く、多くのデータが含まれているため、再設計することはできません。 :(

+1

'machine'を参照する際に' NotFound'マッピングオプションを考慮しましたか?それは安く、パフォーマンス上の理由ではありません。 –

+0

NonFoundマッピング?6年間nHibernateを操作しましたが、聞いたことはありません。うーん、私はすぐにそれを試してみます.. :) –

+0

'NotFound'は、"無効な "外部キー値(ターゲットエンティティテーブルに存在しないID)を扱うためのものですが、どのように役立つか分かりません。 –

答えて

0

私は、これは、マッピングでなんとかなると信じていません。

私は1対多のマシンのみバインド非本番エンティティにマッピングします。

マシンIDなしで一般的なもの( )は専用のクエリで読み込まれ、処理のために2つのリストをマージするでしょう。