2011-11-04 33 views
1

我有以下Nhiberhate流利的映射,但我無法弄清楚如何獲得一個where子句中的一個連接。我只想加入OperationKind ==「TASK」的操作表。任何想法如何acheieve呢?沒有linq之外的映射。where條款在連接映射流利nhibernate

我想看起來像

SELECT X.PHASE_S , PA.INTERVAL, PA.BOR, OP.DESCRIPTION 
FROM GG.PROJ_PHASE_X X 
inner join GG.PHASE PA 
on X.PHASE_S=PA.PHASE_S 
inner join GG.OPERATIONS OP 
ON X.PHASE_S = OP.PHASE_S 
WHERE OP.OPERATION_KIND = 'TASK'; 

映射SQL:

public class MySectionMap : ClassMap<MySectionEntity> 
{ 
    public MySectionMap() 
    { 
     Schema("GG"); 
     Table("PROJ_PHASE_X"); 
     Id(x => x.PhaseS, "PHASE_S").GeneratedBy.TriggerIdentity(); 
     References(x => x.Project).Column("PROJECT_S").Cascade.None().Not.LazyLoad().Not.Nullable(); 
     Join("PHASE", m => 
          { 
           m.Schema("GG"); 
           m.Fetch.Join(); 
           m.KeyColumn("PHASE_S"); 
           m.Map(t => t.Interval).Column("INTERVAL"); 
           m.Map(t => t.BorS).Column("BOR_S"); 
          }); 
     Join("OPERATIONS", m => // ONLY JOIN WHERE OPERATION_KIND EQUALS TASK? 
           { 
            m.Schema("GG"); 
            m.Fetch.Join(); 
            m.KeyColumn("PHASE_S"); 
            m.Map(t => t.Description).Column("DESCRIPTION"); 
            m.Map(t => t.OperationType).Column("OPERATION_KIND"); 
           }); 

    } 
} 

回答

1

Join是從多個錶行的簡單合併成一個實體。你試圖實現的是一個更復雜的 - 你試圖過濾一些值,並在SQL中使用where子句,而不是使用join

你有兩個選擇 - 要麼在數據庫中創建一個視圖並將您的實體映射到視圖(它完全按照表的方式完成)。或第二選擇,更多的代碼,一邊是對應於您的where子句映射水平附加限制:

public MySectionMap() 
{ 
    Schema("GG"); 
    Table("PROJ_PHASE_X"); 

    Join("PHASE", m => //... 
    Join("OPERATIONS", //... 

    Where("OPERATION_KIND = 'TASK'"); 
} 
+0

我其實在做兩個對接和我試圖篩選。由於Operation_kind位於Operations表中,因此您的代碼將無法工作。 我曾考慮過一個視圖,但是在將數據保存回數據庫時會導致問題。 – randoms

+0

'Where可以包含任意的SQL,所以它應該可以工作。你有沒有刪除你的連接?你應該把它留在那裏。 – NOtherDev

+0

由於某種原因,where子句實際上被忽略,它不會在輸出sql中創建一個where。 – randoms

1

的問題是舊的,但無論如何。我有同樣的問題(遺留數據庫,不允許更改模式)。如果它在where子句中,則nhibernate使用引發錯誤的第一個表的別名。

我的解決方案是爲連接定義一個視圖,然後將該視圖用作連接表。無法進入where子句的列也被映射(以便插入也可以工作)。你的情況的看法可能是:

CREATE VIEW FilteredOperations 
    SELECT OP.PHASE_S, OP.DESCRIPTION, OP.OPERATION_KIND 
    FROM GG.OPERATIONS OP 
    WHERE OP.OPERATION_KIND = 'TASK'; 

我流利的映射:

public class Agency : EntityBase 
    { 
     public const string AgencyRoleId = "F1776564-1CA0-11d5-A70C-00A0120802D7"; 

     public Agency() 
     { 
      CountryId = "de"; 
      LanguageId = "de"; 
     } 

     public virtual string AgencyId { get; set; } 
     public virtual string Name { get; set; } 
     public virtual string UserDefinedName { get; set; } 
     public virtual string LanguageId { get; set; } 
     public virtual string CountryId { get; set; } 
     public virtual string RoleId 
     { 
      get 
      { 
       return AgencyRoleId; 
      } 
      set {} 
     } 
    } 

public AgencyMap() 
     { 
      Table("mgmt_location_102"); 
      Id(x => x.AgencyId, "LocationId").GeneratedBy.UuidHex("D"); 
      Map(x => x.CountryId, "CountryId"); 
      Map(x => x.LanguageId, "LanguageId"); 
      Map(x => x.Name,"CommonName"); 

      Join("mgmt_agency_ext", x=> 
             { 
              x.Optional(); 
              x.KeyColumn("AgencyLocationId"); 
              x.Map(y => y.UserDefinedName, "AgencyUserDefinedName"); 

             }); 

      Join("scs2.vAgencyRoles", x => 
      { 
       x.KeyColumn("LocationId"); 
       x.Map(y => y.RoleId, "RoleId").Not.Update(); 
      }); 
     }