简体   繁体   English

如何使用NHibernate中的Criteria API进行自定义投影?

[英]How do I do a custom projection with the Criteria API in NHibernate?

With HQL I can use dynamic instantiation like this: 使用HQL,我可以像这样使用动态实例化:

select new ItemRow(item.Id, item.Description, bid.Amount)
from Item item join item.Bids bid
where bid.Amount > 100

Now I need to create my queries dynamically with the Criteria API. 现在我需要使用Criteria API动态创建我的查询。 How can I obtain the same results that I would have obtained with HQL, but using the Criteria API? 我如何获得与使用HQL获得的结果相同的结果,但使用Criteria API?

Thank you. 谢谢。

You can use the AliasToBean result transformer. 您可以使用AliasToBean结果转换器。 ( Doc 1.2 ) It assigns every projection to a property of the same name. Doc 1.2 )它将每个投影分配给同名的财产。

session.CreateCriteria(typeof(Item), "item")
  .CreateCriteria("Bids", "bid")
  .SetProjection(Projections.ProjectionList()
    .Add(Projections.Property("item.Id"), "Id" )
    .Add(Projections.Property("item.Description"), "Description" )
    .Add(Projections.Property("bid.Amount"), "Amount" ))
  .Add(Expression.Gt("bid.Amount", 100))
  .SetResultTransformer(Transformers.AliasToBean(typeof(ItemRow)))
  .List();

Assuming you are using NHibernate 2.0.1 GA, here is the pertinent documentation: 假设您使用的是NHibernate 2.0.1 GA,以下是相关文档:

http://nhibernate.info/doc/nh/en/index.html#querycriteria-projection http://nhibernate.info/doc/nh/en/index.html#querycriteria-projection

Hope that helps! 希望有所帮助!

When you use a projection, the return type becomes Object or Object[] instead of the criteria type. 使用投影时,返回类型将变为Object或Object [],而不是条件类型。 You have to use a transformer. 你必须使用变压器。

Here is a simple ResultTransformer: 这是一个简单的ResultTransformer:

 private class ProjectionTransformer implements ResultTransformer {
        private String[] propertysList;
        private Class<?> classObj;

        /**
         * @param propertysList
         */
        public ProjectionTransformer(String[] propertysList) {
            this.classObj = persistentClass;
            this.propertysList = propertysList;
        }

        /**
         * @param classObj
         * @param propertysList
         */
        public ProjectionTransformer(Class<?> classObj, String[] propertysList) {
            this.classObj = classObj;
            this.propertysList = propertysList;
        }

        @SuppressWarnings("unchecked")
        public List transformList(List arg0) {
            return arg0;
        }

        public Object transformTuple(Object[] resultValues, String[] arg1) {
            Object retVal = null;
            try {
                retVal = Class.forName(classObj.getName()).newInstance();
                int dot = -1;
                for (int i = 0; i < resultValues.length; i++) {
                    if ((dot = propertysList[i].indexOf(".")) > 0) {
                        propertysList[i] = propertysList[i].substring(0, dot);
                    }
                    PropertyUtils.setProperty(retVal, propertysList[i], resultValues[i]);
                }
            } catch (Exception e) {// convert message into a runtimeException, don't need to catch
                throw new RuntimeException(e);
            }
            return retVal;
        }
    }

Here's how you use it: 以下是您使用它的方式:

ProjectionList pl = (...)
String[] projection = new String[]{"Id","Description","Bid.Amount"};
crit.setProjection(pl).setResultTransformer(new ProjectionTransformer(projection));

I have not tested it for relations (eg: Bid.Amount). 我没有测试它的关系(例如:Bid.Amount)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM