2012-04-19 87 views
0

考慮以下配置:NHibernate的產奇SQL的一個一對多的集合

<class name="CategoryPerm" table="CUS_BCDynamicContent_CategoryPerms" lazy="true" > 
    <id name="Id"> 
     <generator class="guid.comb" /> 
    </id> 
    <many-to-one class="BCDynamicContent.Entities.Category, BCDynamicContent, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" name="Category"> 
     <column name="CategoryID" sql-type="uniqueidentifier" not-null="true" /> 
    </many-to-one> 
    <property name="PortalGroupId"> 
     <column name="PortalGroupID" sql-type="uniqueidentifier" /> 
    </property> 
    <bag name="GroupMemberships" cascade="none"> 
     <key column="ParentPrincipalID" property-ref="PortalGroupId" /> 
     <one-to-many class="BCDynamicContent.Entities.GroupMembership, BCDynamicContent, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </bag> 
</class> 
<class name="GroupMembership" table="FWK_GroupMembership" lazy="true" mutable="false" > 
    <id name="Id"> 
    </id> 
    <property name="ParentPrincipalId"> 
     <column name="ParentPrincipalID" sql-type="uniqueidentifier" not-null="true" /> 
    </property> 
    <property name="MemberPrincipalId"> 
     <column name="MemberPrincipalID" sql-type="uniqueidentifier" not-null="true" /> 
    </property> 
</class> 

及其類別:

public class Entity 
{ 
    public virtual Guid Id { get; set; } 
} 


public class CategoryPerm : Entity 
{ 
    public virtual Category Category { get; set; } 
    public virtual Guid PortalGroupId { get; set; } 
    public virtual IList<GroupMembership> GroupMemberships { get; set; } 

    public CategoryPerm() 
    { 
     GroupMemberships = new List<GroupMembership>(); 
    } 
} 


public class GroupMembership : Entity 
{ 
    public virtual Guid ParentPrincipalId { get; private set; } 
    public virtual Guid MemberPrincipalId { get; private set; } 

} 

而下面的LINQ查詢:

var categories = (from x in nhs.Linq<CategoryPerm>() where x.GroupMemberships.Any(y => y.MemberPrincipalId == PortalUser.Current.ID) select x).ToList() ; 

爲什麼NH出現的sql看起來像這樣:(問題一是「exists()」部分「where this_0_.Id = ParentPrin cipalID「< - 不應該這樣做)

SELECT this_.Id   as Id290_0_, 
     this_.CategoryID as CategoryID290_0_, 
     this_.PortalGroupID as PortalGr3_290_0_ 
FROM CUS_BCDynamicContent_CategoryPerms this_ 
WHERE this_.Id in (SELECT this_0_.Id as y0_ 
        FROM CUS_BCDynamicContent_CategoryPerms this_0_ 
          inner join FWK_GroupMembership y1_ 
          on this_0_.PortalGroupID = y1_.ParentPrincipalID 
        WHERE exists(select 1 
            from FWK_GroupMembership 
            where this_0_.Id = ParentPrincipalID) 
          and y1_.MemberPrincipalID = 'b32f5d6c-490c-45e9-874a-c4d27d2862b8' /* @p0 */) 
+0

,感謝你們給予生成的SQL看起來是正確的LINQ查詢,它正在爲'你曾經使用過 – Baz1nga 2012-04-20 01:20:20

+0

這是非常接近正確Any' API生成,但並不完全。注意它說「this_0_.Id = ParentPrincipalID」。它應該說「this_0_.PortalgroupID = ParentPrinciplalID」,就像它在父SQL中的from中加入一樣。所以linq在大部分語句中尊重父類>子類的列,除了在「存在」部分中,它似乎完全忽略它。 – Wyza 2012-04-20 02:24:37

回答

0

看起來這是NH 2.x Linq提供程序中的一個錯誤。我最終選擇了ICriteria,現在它就像一個魅力一樣。

nhs.CreateCriteria<CategoryPerm>("a").CreateCriteria("a.Category", "b").CreateCriteria("a.GroupMemberships", "c").Add(
       Restrictions.Eq("c.MemberPrincipalId", PortalUser.Current.ID.AsGuid)).List<CategoryPerm>();