Надеюсь, я правильно понял вашу проблему, поэтому вы просто хотите, чтобы все авторы, у которых есть хотя бы одна бумага, у которой этот флаг установлен на true, правильно?
Почему вы не просто используете Linq, его способ проще писать и должен работать для таких простых сценариев. Я хотел бы также сопоставить свой флаг на BOOL, так что я думаю, что нет необходимости делать Max
операцию на все ... Примера:
var authorsWithPublications = session.Query<Paper>()
.Select(p => new { Author = p.Author, HasPublished = p.HasPublished })
.Where(p => p.HasPublished == true).ToList();
Я использовал этот простой сценарий, дайте мне знать, если это Безразлично «т соответствует ваш вопрос:
Entity + Mapping:
public class Paper
{
public virtual int Id { get; set; }
public virtual string Author { get; set; }
public virtual bool HasPublished { get; set; }
public virtual string Description { get; set; }
public virtual string Something { get; set; }
public virtual string SomethingElse { get; set; }
}
public class PaperMap : ClassMap<Paper>
{
public PaperMap()
{
Id<int>("Id");
Map(p => p.Author);
Map(p => p.HasPublished);
Map(p => p.Description);
Map(p => p.Something);
Map(p => p.SomethingElse);
}
}
Создание некоторых тестовых данных и запрос
using (var session = sessionFactory.OpenSession())
{
Random r1 = new Random();
for (int i = 0; i < 100; i++)
{
session.Save(new Paper()
{
Author = "Author" + i,
HasPublished = r1.Next(0, 2) == 0 ? false : true,
Description = "Description" +i,
Something = "Something" + i,
SomethingElse = "something else" + i
});
}
session.Flush();
var authorsWithPublications = session.Query<Paper>()
.Select(p => new { Author = p.Author, HasPublished = p.HasPublished })
.Where(p => p.HasPublished == true).ToList();
}
Это на самом деле возвращает меня именно эти авторы ... Вы могли бы обработать это еще иметь только отличный результат ...
: редактировать начинается: для запроса всех авторов с максимальным значением флага , то становится немного сложнее с LINQ, следующий запрос LINQ вернет этот результат:
var authorsWithPublications = session.Query<Paper>()
.GroupBy(p => new { Author = p.Author })
.Select(p => new {
Author = p.Key,
HasPublished = p.Max(c=> c.HasPublished)
})
.ToList();
Но если c.HasPublished битового поля в SqlServer, это даст вам исключение SQL, что макс не разрешено в полях бит.
Попытка преобразовать логическое значение в целое wihtin заявление Linq как
...HasPublished = p.Max(c => c.HasPublished == true ? 1 : 0)
сгенерирует исключение Code supposed to be unreachable
, потому что он не поддерживается NHibernate ...
Единственный способ, которым я нашел, чтобы получить первый Linq ход запроса является заданием формулы в отображении:
Map(p => p.HasPublished).Formula("cast (HasPublished as int)");
Теперь эта формула будет применяться для всех операторов выбора, оператор будет выглядеть следующим образом:
select paper0_.Author as col_0_0_, max(cast (paper0_.HasPublished as int)) as col_1_0_
from [Paper] paper0_
group by paper0_.Author
в любом случае вы уже нашли решение и следующий делает фактически то же самое, без необходимости формулы
var criteria = session.CreateCriteria<Paper>();
criteria.SetProjection(
Projections.Group<Paper>(p=>p.Author),
Projections.Max(
Projections.Cast(NHibernateUtil.Int32, Projections.Property("HasPublished")))
);
var result = criteria.List();
Но, может быть, мы оба чему-то научились;)
Я нашел решение своей непосредственной проблемы. 'Projections.Max' перегружен несколько раз, одна перегрузка может просто взять другую проекцию, в данном случае' Projections.Cast'. Таким образом, линия нужно быть таким: 'Projections.Max ( Projections.Cast (NHibernateUtil.Int32, Projections.Property ("major_journal")) .WithAlias (() => report.EverPublished)' Мой оригинал попытка заключалась в использовании излишне сложной версии «Projections.Max». – phil