Как сделать пользовательский прогноз с помощью API Criteria в NHibernate? - PullRequest
4 голосов
/ 05 апреля 2009

С HQL я могу использовать динамическое создание, например:

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

Теперь мне нужно динамически создавать свои запросы с помощью API Criteria. Как я могу получить те же результаты, которые я получил бы с HQL, но используя Criteria API?

Спасибо.

Ответы [ 3 ]

7 голосов
/ 15 апреля 2009

Вы можете использовать преобразователь результатов AliasToBean. ( 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();
1 голос
/ 14 апреля 2009

Когда вы используете проекцию, тип возвращаемого значения становится Object или Object [] вместо типа критерия. Вы должны использовать трансформатор.

Вот простой результатTransformer:

 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;
        }
    }

Вот как вы его используете:

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

Я не проверял его на отношения (например: Bid.Amount).

1 голос
/ 05 апреля 2009

Если вы используете NHibernate 2.0.1 GA, вот соответствующая документация:

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

Надеюсь, это поможет!

...