nHibernate, OR clause with .withSubquery - nhibernate

How can we force nHibernate to generate “OR” clause instead of “AND” clause when using “.withSubquery”
var includeSharedTemplateCategories= EntityFinder.Of<TemplateMappers.FolderEntity>() .Where(e => e.MID == effectiveMemberID) .Where(e => e.CategoryType == "shared_template") .SelectList(e => e.Select(c => c.Id));
var includeNormalCategories = EntityFinder.Of<TemplateMappers.FolderEntity>()
.Where(e => e.MID == MemberID)
.Where(e => e.CategoryType == "template")
.SelectList(e => e.Select(c => c.Id));
var query = EntityFinder.Of<TemplateMappers.TemplateEntity>()
.Where(f => f.TemplateIsActive == 1)
.RestrictionByQuery<TemplateMappers.TemplateEntity, TemplateObject>(options)
.WithSubquery.WhereProperty(e => e.CategoryId).In(includeSharedTemplateCategories)
.WithSubquery.WhereProperty(e => e.CategoryId).In(includeNormalCategories)
.SelectByQuery<TemplateMappers.TemplateEntity, TemplateObject>(options)
.OrderByQuery<TemplateMappers.TemplateEntity, TemplateObject>(options);
“And” is used in condition
this_.fkcategoryid IN (SELECT this_0_.pkcategoryid AS y0_
FROM categories this_0_
WHERE this_0_.mid = xyz AND this_0_.categorytype = 's_template')
And this_.fkcategoryid IN (SELECT this_0_.pkcategoryid AS y0_ FROM categories this_0_
WHERE this_0_.mid = abc AND this_0_.categorytype = 'template');
I’m looking for “OR“ clause between sub-queries.
this_.fkcategoryid IN (SELECT this_0_.pkcategoryid AS y0_ FROM categories this_0_ WHERE this_0_.mid = xyz AND this_0_.categorytype = 's_template')
**OR** this_.fkcategoryid IN (SELECT this_0_.pkcategoryid AS y0_ FROM dbo.tblcategories this_0_ WHERE this_0_.mid = abc AND this_0_.categorytype = 'template');
kris.

var includeSharedAndNormalTemplateCategories = EntityFinder.Of<FolderEntity>()
.Where(e => (e.MID == effectiveMemberID && e.CategoryType == "shared_template") ||
(e.MID == MemberID && e.CategoryType == "template"))
.Select(e => e.Id);
var query = EntityFinder.Of<TemplateEntity>()
.Where(f => f.TemplateIsActive)
.RestrictionByQuery<TemplateEntity, TemplateObject>(options)
.WithSubquery.WhereProperty(e => e.CategoryId).In(includeSharedAndNormalTemplateCategories)
.SelectByQuery<TemplateEntity, TemplateObject>(options)
.OrderByQuery<TemplateEntity, TemplateObject>(options);
SideNote: TemplateIsActive should be/is bool no?

Related

How to perform following query in LINQ?

I have a SQL query need to do in LINQ. Can anyone helps in converting?
SELECT *
FROM profile
WHERE ProfileId <> 1221 AND IsActive = 1 AND
ProfileId NOT IN (SELECT ReportingPerson
FROM ReportingPersons
WHERE Employee = 1221)
var reportingPerson = context.ReportingPersons.Where(x =>
x.Employee == 1221)
.Select(c => c.ReportingPerson
).ToList();
var result = context.Profiles
.Where(x =>
x.ProfileId != 1221 &&
x.IsActive &&
!reportingPerson.Contains(x.ProfileId)
.ToList();

How to Convert Sql to Linq with Distinct(id)

select count(distinct LicencePlate) from MT_Vehicle where IsDeleted=0 and CreatedBy = 1
var count = MT_Vehicle.Where(x => x.IsDeleted==0 && x.CreatedBy == 1)
.Select(x => x.LicencePlate)
.Distinct()
.Count();
You can write that as:
var count = db.MT_Vehicle
.Where( v => v.IsDeleted == 0 && v.CreatedBy == 1 )
.Select(v => v.LicencePlate)
.Distinct()
.Count();

NHibernate Query subquery group by join back to main entity

Hello i'm trying to achieve the following SQL
SELECT this_.*
FROM WorkItems this_
WHERE this_.UserId = (
SELECT this_1_.y0_ as y0_
FROM
(
SELECT top 1 this_0_.UserId as y0_, count(this_0_.UserId) as y1_
FROM WorkItems this_0_
WHERE this_0_.StateId = 1 and this_0_.Type like 'Data'
GROUP BY this_0_.UserId
ORDER BY y1_ desc
) this_1_
);
so far i have manged to produce something fairly close. I'm missing the part where i just select out the userId.
heres the query so far
var subquery = QueryOver.Of<WorkItem>().Where(w => w.State == state)
.AndRestrictionOn(w => w.Type).IsLike(type, MatchMode.Exact)
.SelectList(list =>
list.SelectGroup(w => w.UserId)
.WithAlias(() => resultAlias.userId)
.SelectCount(w => w.UserId)
.WithAlias(() => resultAlias.count))
.OrderByAlias(() => resultAlias.count)
.Desc().Take(1);
var query =
CurrentSession.QueryOver<WorkItem>()
.WithSubquery
.WhereProperty(p => p.UserId)
.Eq(subquery);
Try this: -
var subquery = QueryOver.Of<WorkItem>().Where(w => w.State == state)
.AndRestrictionOn(w => w.Type).IsLike(type, MatchMode.Exact)
.SelectList(list => list.SelectGroup(w => w.UserId))
.OrderBy(Projections.Count<WorkItem>(x => x.UserId))
.Desc().Take(1);
var query = CurrentSession.QueryOver<WorkItem>()
.WithSubquery
.WhereProperty(p => p.UserId)
.Eq(subquery);

Nhibernate QueryOver: Count in where clause

Any tips on how to convert the following to QueryOver:
var widget = session.Query<Widget>()
.Fetch(x => x.NotificationJobs)
.Where(x =>
x.Status == Status.Active &&
!x.NotificationJobs.Any())
.OrderByDescending(x => x.DateCreated)
.Take(1)
.SingleOrDefault();
Want to get a widget that has no notification jobs.
var widgetWithNoNotificationJob = session.QueryOver<Widget>()
.Where( x => x.Status == Status.Active )
.OrderBy( x => x.DateCreated ).Desc
.Left.JoinQueryOver<NotificationJob>( x => x.NotificationJobs )
.Where( x => x.NotificationJobId == null )
.Take( 1 )
.SingleOrDefault();
This will produce SQL with a LEFT OUTER JOIN on the NotificationJob table and a WHERE clause with NotificationJob.NotificationJobId IS NULL.
Hopefully this will point you in the right direction.

NHibernate QueryOver subquery to return only newest record

I have a query in Nhibernate QueryOver which brings back a collection of episode objects (episode being a spell of care) which in turn has a collection of episode statuses as a property of each episode. However I want to change this so that each episode only brings back the latest status update for that episode instead of all of them.
The SQL to do this is as follows:
SELECT *
FROM DIPEpisode e
INNER JOIN DIPEpisodeStatus s on s.EpisodeID = e.SequenceID
WHERE e.ClientID = '1000001'
AND s.SequenceID IN (
SELECT TOP 1 SequenceID
FROM DIPEpisodeStatus s
WHERE s.EpisodeID = e.SequenceID
ORDER BY StatusRecordedDate DESC
)
I have written the following query which gives me almost exactly what I need
var statuses =
QueryOver.Of<DIPEpisodeStatus>()
.OrderBy(x => x.StatusRecordedDate).Desc
.Select(x => x.Id).Take(1);
DIPEpisodeStatus statusAlias = null;
return
session.QueryOver<DIPEpisode>()
.JoinQueryOver(x => x.DIPEpisodeStatuss, () => statusAlias)
.Fetch(x => x.AgencyID).Eager
.Fetch(x => x.DIPEpisodeStatuss).Eager
.Where(e => e.ClientID.Id == this.clientId)
.WithSubquery.WhereProperty(x => x.Id).Eq(statuses)
.List();
This generates the following SQL:
SELECT *
FROM DIPEpisode this_
inner join DIPEpisodeStatus statusalia1_
on this_.SequenceID = statusalia1_.EpisodeID
WHERE statusalia1_.ClientID = '1000001' /* #p0 */
and statusalia1_.SequenceID = (SELECT TOP (1 /* #p1 */) this_0_.SequenceID as y0_
FROM DIPEpisodeStatus this_0_
ORDER BY this_0_.StatusRecordedDate desc)
As you can see, the only thing missing is the where clause from the subquery. What changes do I need to make to the query in order to generate this extra where clause and pull back only the most recent status update?
Thanks
Ben
the collection DIPEpisodeStatuss is always initialized with all entities because it would break changetracking otherwise. you could either define a filter for the collection or return a DTO with what you want. Also the fetch will be ignored because it can not eager load and filter in one sql statement.
NHibernate filters are explained here
defining Filters in FNH
how it would be done with a DTO
// assuming SequneceID and StatusRecordedDate correlates
var subquery = QueryOver.Of<DIPEpisode>()
.Where(e => e.ClientID.Id == this.clientId)
.JoinAlias(e => e.DIPEpisodeStatuss, () => statusAlias)
.Select(Projections.Max(() => statusAlias.SequenceID));
// or as in question
var subquery = QueryOver.Of<DIPEpisode>()
.Where(e => e.ClientID.Id == this.clientId)
.JoinAlias(e => e.DIPEpisodeStatuss, () => statusAlias)
.OrderByDescending(() => statusAlias.StatusRecordedDate)
.Select(() => statusAlias.SequenceID)
.Take(1);
DIPEpisodeDto dto = null;
DIPEpisodeStatus statusAlias = null;
return session.QueryOver<DIPEpisode>()
.Where(e => e.ClientID.Id == this.clientId)
.JoinQueryOver(e => e.DIPEpisodeStatuss, () => statusAlias)
.WithSubquery.WhereProperty(estatus => estatus.Id).Eq(statuses)
.SelectList(list => list
.Select(e => e.Whatever).WithAlias(() => dto.Whatever)
.Select(() => statusAlias.SquenceId).WithAlias(() => dto.StatusId)
...
)
.TransFormUsing(Transformers.AliasToBean<DIPEpisodeDto>())
.List();
or using LINQ
var query = from e in session.Query<DIPEpisode>()
from s in e.DIPEpisodeStatuss
where e.ClientID.Id == this.clientId
where s.Id == (
from e2 in session.Query<DIPEpisode>()
from s2 in e2.DIPEpisodeStatuss
orderby s2.StatusRecordedDate descending
select s2.Id)
.First()
select new DIPEpisodeDto
{
e.Prop1,
Status = s,
};
return query.List<DIPEpisodeDto>();