基于运行时动态条件的属性映射

时间:2010-02-25 19:27:03

标签: c# nhibernate hql criteria

我一直在谷歌上搜索寻找答案无效的网页,但我认为我只是错误地表达了这个问题。

场景如下:我有一个用户可以投票赞成或反对的实体。为了论证,我们可以将实体称为业务。

我想在我的商务舱中拥有一个属性,该属性指示当前登录的用户如何为该特定商家投票。也就是说,我希望在用户向上显示一个绿色勾号,并在用户投票的地方显示红色十字。

在SQL中这是直截了当的,我可以创建一个SQL函数,它根据参数“:userid”执行此解析,更具体地说,它可以传递给proc。即。

   SELECT
      BusinessId,
      CreatedOn,
      Username,
      [Content].ResolveBusinessVoteIndicator(:userid, P.BusinessId) AS VoteIndicator
   FROM 
      Content.Business P

这里的主要问题是我必须创建一个映射到存储过程结果的实体。这是不好的,因为现在我不能使用HQL或Criteria,这将是首选方法。

另一种选择是进行查询,然后简单地遍历结果并设置该属性,如果您一次查看一个业务,这将有效,但我需要一次显示大量业务

所以我想问题是......是否有办法使用HQL或Criteria映射属性,其中该映射基于需要在运行时输入的公式?类似于将参数传递给存储过程并映射结果。

2 个答案:

答案 0 :(得分:0)

在这种情况下,你真的在​​谈论ViewModel。您不应该在Business实体上拥有该属性,而应该创建一个视图模型,该模型表示具有您正在讨论的标志的业务实体。

如果您真的想使用NHibernate执行此操作,请在数据库中创建一个View并将视图模型映射到视图。然后你可以像对待任何其他对象一样对它运行HQL / Criteria。我做了很多,而且效果很好。

您还可以使用数据集从存储过程中获取结果,并绑定到数据集。请记住,您的域模型(业务实体)与您的视图模型(带有投票的业务类)不同,并且可能不应该使用相同的数据访问代码运行。

Greg Young在他的博客上谈论了这种方法。例如:http://codebetter.com/blogs/gregyoung/archive/2010/02/15/cqrs-is-more-work-because-of-the-read-model.aspx

答案 1 :(得分:0)

如果您想为每个业务需求创建一个视图,Derick的答案是合理的。

您想要完成的任务可以使用IFilter完成。 考虑Business

上的这个hbm.xml映射属性
<property name="IsVoted" type="boolean" update="false" insert="false" formula="(SELECT [Content].ResolveBusinessVoteIndicator(:loggedOnUser.userId, BusinessId)"/>

以及课程本身

 public bool IsVoted {get;set;}

请注意,BusinessId存储过程中的ResolveBusinessVoteIndicator参数必须是Business表的Id列,NHibernate将为其创建适当的allias。 现在,这取决于可以在单独的文件上定义的以下xml元素(比如filters.hbm.xml)

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <filter-def name="loggedOnUser">
        <filter-param name="userId" type="Int32"/>
    </filter-def>
</hibernate-mapping>

并在运行时以编程方式启用过滤器,如

nhSession.EnableFilter("loggedOnUser").SetParameter("userId", GetLoggedOnUserId());
在运行查询之前

。此外,您可以直接在hql中使用它(伪-hql:'来自Business b,其中b.IsVoted = true'来获取所有已投票的业务)