У меня есть сущности с базовым классом, подобным этому:
public class MyEntity
{
public int Id { get; set; } //primary key
public int EntityId { get; set; } //not foreign key, just number; used for assosiate with other versions of entity
public int EntityState { get; set; } //1 - Actual, 3 - Draft
public int Version { get; set; }
}
Я пытаюсь получить запрос для похожих SQL:
-- 'ed' means 'entityDraft' and 'ea' means 'entityActual'
SELECT ed.*, ea.*
FROM MyEntity ed
LEFT JOIN MyEntity ea ON ed.EntityState = 3 AND ea.EntityState = 1 AND ed.EntityId = ea.EntityId
WHERE ea.Id is NULL OR ed.Version != ea.Version
Почему я хочу Отдельные крематории вместо обычных JoinWithAlias? - Потому что мне нужно иметь возможность указывать ГДЕ в качестве параметра.
Я сделал запрос LINQ, но он не работает для меня, потому что мне нужна версия generic c, которая также получает некоторые 'Fetch' в качестве параметров, что я не могу сделать с LINQ.
Моя версия LINQ, если вам это нужно:
// DraftAndApproved<T> is just simple structure for mapping result
var draftsForApprove = session.Query<T>().Where(e => e.EntityState = 3)
.GroupJoin(session.Query<T>().Where(e => e.EntityState = 1),
draft => draft.Extension.EntityId,
approved => approved.Extension.EntityId,
(draft, approvedJoin) => new { draft, approvedJoin = approvedJoin.DefaultIfEmpty() })
.SelectMany(j =>
j.approvedJoin.Select(approved =>
new DraftAndApproved<T> { Draft = j.draft, Approved = approved }))
.Where(predicate)
.Select(da => da)
.ToArray();
Предикат получения в качестве параметра: Expression<Func<DraftAndApproved<T>,bool>> predicate
Для лучшего понимания того, что я хочу, вот пример кода PSEUDO:
var draftForApprove = DetachedCriteria.For<T>("draftAlias")
.Join<T>("approvedAlias", JoinType.LeftOuterJoin)
.Add(Restrictions.Eq(Projections.Property("draftAlias.EntityState"), 3))
.Add(Restrictions.Eq(Projections.Property("approvedAlias.EntityState"), 1))
.Add(Restrictions.Eq(Projections.Property("draftAlias.EntityId"), Projections.Property("approvedAlias.EntityId")))
.Add(additionalClause)
.SetProjection
(
Projections.ProjectionList()
.Add(Projections.Property("draftAlias"), "Draft")
.Add(Projections.Property("approvedAlias"), "Approved")
)
.SetResultTransformer(Transformers.AliasToBean<DraftAndApproved<T>>());
Где additionalClause
- ICriterion
Получение из параметров.