Самостоятельное соединение с DetachedCriteria без связанного свойства - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть сущности с базовым классом, подобным этому:

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 Получение из параметров.

...