查询私有引用的属性
我有一个与其父级是多对一的课程。我想通过子级公开父级的属性,而不直接公开父级。我还想查询这些属性并按这些属性排序。
类
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);
}
}
}
问题在于,这会导致“无法解析属性:OrganizationName”错误。看起来我可以使用公式映射这些字段,但最终我会为已加入查询的表上的每个字段进行子选择。或者,我可以使用公共 getter 包装联系人的组织,并将查询更改为 OrderBy(x => x.Organization.Name)。但这让我违反了德米特法则。
我是不是偏离了轨道?我应该如何处理这个问题?
已编辑以显示分页
I have a class that is many-to-one with its parent. I'd like to expose the parent's properties through the child without exposing the parent directly. I'd also like to query on and order by those properties.
Classes
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; } }
}
Mapping
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();
}
}
Query
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);
}
}
}
The problem is that this results in a "Could not resolve property: OrganizationName" error. It looks like I could map those fields with a formula, but then I'd end up with a sub-select for each field on a table that's already joined into my query. Alternatively, I could wrap the Contact's organization with a public getter and change my query to OrderBy(x => x.Organization.Name). That leaves me with a Law of Demeter violation though.
Am I off track? How should I handle this?
edited to show paging
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不能在查询中使用非映射属性。 NHibernate 如何知道如何为其创建 SQL 条件?在您的情况下,这可能很容易,但是如果您要调用该属性中的方法或一些复杂的逻辑怎么办?
所以是的,您至少需要一个公共吸气剂属性。
或者,在内存中进行排序(在 NHibernate 执行查询之后)。
You can't use non-mapped properties in queries. How should NHibernate know how to create a SQL condition for it? In your case it might be easy, but what if you'd have a call to a method or some complicated logic in that property?
So yes, you need at least a public getter property.
Alternatively, do the sorting in memory (after NHibernate has executed the query).