2011-06-27 69 views
0

我有一个与其父母多对一的类。我想通过孩子暴露父母的属性,而不直接暴露父母。我也想查询和订购这些属性。查询私人参考的属性

public class Organization 
{ 
    public virtual string Name { get; set; } 
    public virtual bool IsNonProfit { get; set; } 
} 

public class Contact 
{ 
    private Organization _organization; 
    public virtual string OrganizationName 
     { get { return _organization.Name; } } 
    public virtual bool OrganizationIsNonProfit 
     { get { return _organization.IsNonProfit; } } 
} 

映射

public class OrganizationMap : ClassMap<Organization> 
{ 
    public OrganizationMap() 
    { 
     Map(x => x.Name); 
     Map(x => x.IsNonProfit); 
    } 
} 

public class ContactMap : ClassMap<Contact> 
{ 
    public ContactMap() 
    { 
     References<Organization>(Reveal.Member<Contact>("_organization")) 
      .Access.CamelCaseField(); 
    } 
} 

查询

public class Example 
{ 
    private ISessionFactory _sessionFactory; 

    public Example(ISessionFactory sessionFactory) 
    { 
     _sessionFactory = sessionFactory; 
    } 

    public IEnumerable<Contact> DoQuery(int forPage, int rowsPerPage) 
    { 
     using (var session = _sessionFactory.OpenSession()) 
     { 
      return session.Query<Contact>().OrderBy(x => x.OrganizationName) 
       .Skip((forPage - 1) * rowsPerPage).Take(rowsPerPage); 
     } 
    } 
} 

的问题是,这会导致我n“无法解析属性:OrganizationName”错误。看起来我可以用公式映射这些字段,但是最后我会为已经加入到查询中的表上的每个字段选择一个子选择。或者,我可以使用公共getter来包装联系人的组织,并将我的查询更改为OrderBy(x => x.Organization.Name)。尽管如此,我还是违反了德米特法。

我偏离了轨道吗?我该如何处理?

编辑,以显示分页

回答

0

不能在查询中使用非映射属性。 NHibernate应该如何知道如何为它创建一个SQL条件?在你的情况下,它可能很容易,但如果你有一个方法的调用或该属性中的一些复杂的逻辑呢?

所以是的,你至少需要一个公共的getter属性。

另外,做内存中的排序(在NHibernate执行查询后)。

+0

谢谢;在实践中,我将这种排序与分页相结合,因此在内存中排序并不实际。随着公共获得者你提倡LoD违规呢?我正在考虑它;我只是不知道我会停下来。当它是session.Query ().Where(x => Organization.HeadQuarters.Location.City ==“迈阿密”)? –

+0

@Eric是,无论是该属性还是公式属性(这可能会导致SQL性能不佳)。至少对于Linq查询,我不知道Criteria/QueryOver中是否有方法。 – cremor