I have a question. I have this query:
var query = QueryOver.Of<Item>()
.JoinQueryOver<ItemRelation>(p => p.ItemRelation)
.Where(r => r.Item1.Id == itemId)
How can I return only Item entity but not Item Relation?
Thanks
The query actually should only return Predmet ... The RelacijaPredmeta is a property of it. If you don't want to load it, use lazy loading, or select the properties of Predmet individually.
Related
I would like to restrict a query using the QueryOver mechanism in Fluent Nhibernat. I found that I can do this using WhereRestrictOn but there seems to be no possibility to compare to just one value. A IsEqual method of sorts.
I quick example might explain better what my issue is
class Parent{
IList<Child1> C1 {get;set;}
IList<Child2> C2 {get;set;}
}
class Child1{
int Id {get;set;}
}
class Child2{
int Id {get;set;}
}
//What I can do
var result = session.QueryOver<Parent>()
.WhereRestrictionOn(x => x.C1.Id).IsIn(new[]{3})
.AndRestrictionOn(x => x.C2.Id).IsIn(new[]{5}).List();
//What I would like to do
var result = session.QueryOver<Parent>()
.WhereRestrictionOn(x => x.C1.Id).IsEqual(3)
.AndRestrictionOn(x => x.C2.Id).IsEqual(5).List();
So basically my issue is that I'm not able to compare with one value but always have to artifically create an array. Is this not possible or am I missing something?
If it is possible please tell me how. If it is not possible I would appreciate an explantion as to why not.
Thanks in advance.
Try this:
Child1 c1Alias = null;
Child2 c2Alias = null;
var result = session.QueryOver<Parent>()
.InnerJoin(x => x.C1, () => c1Alias) // or use Left.JoinAlias
.InnerJoin(x => x.C2, () => c2Alias) // or use Left.JoinAlias
.Where(() => c1Alias.Id == 3)
.And(() => c2Alias.Id == 2)
.List();
I think you want a pair of Subqueries rather than a restriction, but you'll have to map the ParentID value in both Child1 and Child2.
Each SubQuery should return the ParentID where the childID is your search value, and then you can use a conjunction to return the Parent for both children, or null if there isn't one, I suppose.
I am trying to use query over to retrieve a collection of entities based upon a join/subquery as per the example below:
var types = new List<ActivityType>{ActivityType.CommentMedia, ActivityType.KeepMedia};
return _sessionFactory.GetCurrentSession()
.QueryOver<Activity>()
.Where(a.Type.IsIn(types))
.WithSubquery.WhereExists(QueryOver.Of<Resource>()
.Where(k => k.MemberKey == userId)
.Where(k => k.ResourceKey == activity.ResourceId)
)
.Take(take)
.List();
In other words retrieve all activities which are in the resource table matching the user and resource id.
I would do this in raw sql by either joining to Resource, or a subquery:
where a.ResourceId in (select resourceKey from resource where resource.memberkey = a.MemberId)
Not sure how to proceed in nhibernate though. Any suggestions?
(We don't want to use a mapping, as we want to keep the Activity entity very simple for performance reasons)
Thanks in advance
Activity activity = null;
return _sessionFactory.GetCurrentSession()
.QueryOver(() => activity)
.Where(a.Type.IsIn(types))
.WithSubquery.WhereProperty(a => a.ResourceId).In(QueryOver.Of<Resource>()
.Where(k => k.MemberKey == userId)
.Where(k => k.ResourceKey == activity.ResourceId)
)
.Take(take)
.List();
I have 2 entities, linked via a Many to Many called Parent and Child.
In Child I have an IList of Parents,
In Parent I have an IList of Childs.
I am trying to do a query on a list of parents, that is linked to a child.
Conceptually wise, I am looking for something like this:
var Query = session.QueryOver<Parent>()
Query.Where(o => o.Children.Contains(child));
But this won't work, so what ways can I get this to work?
Thanks!
You need to use JoinQueryOver
session.QueryOver<Parent>().JoinQueryOver<Child>(p => p.Childs)
.Where(c => c.Id == child.Id)
var query = session.QueryOver<Parent>()
.Where(o => o.Children.Contains(child));
or
var query = session.Query<Parent>()
.Where(o => o.Children.Contains(child));
or see Vadim
I would like to make this query:
Session.Linq<User>().Where(u => u.Payments.Count(p => p.Date != null) > 0);
In plain English I want to get all the users that has at least one payment with the date specified.
When I run the sample code I get a System.ArgumentException with the message:
System.ArgumentException : Could not find a matching criteria info provider to: this.Id = sub.Id
Do you know a solution to this problem?
It would also be very helpful if someone could provide the same query with the NHibernate Query by Criteria API.
I'm not sure if this will work in your particular case, but I would use the .Any() extension to clean up the linq query a bit; for example:
Session.Linq<User>().Where(u => u.Payments.Any(p => p.Date != null));
I think something like it:
Customer customerAlias = null;
criteria = CurrentSession.CreateCriteria(typeof(User), () => customerAlias);
if (searchCriteria.OrdersNumber.HasValue)
{
ICriteria paymentsCriteria = criteria.CreateCriteria<Customer>(x => x.Payments);
DetachedCriteria paymentsCount = DetachedCriteria.For<Payment>();
paymentsCount.SetProjection(Projections.RowCount());
paymentsCount.Add(SqlExpression.NotNull<Payment>(x => x.Date));
paymentsCount.Add<Payment>(x => x.Customer.Id == customerAlias.Id);
paymentsCriteria.Add(Subqueries.Gt(1, paymentsCount));
}
return criteria.List<User>();
Here is a simple example scenario -
A 'Tag' has many 'Questions'. When I get a list of Tags how do I order by the Tags Question Count using the Criteria API?
I have done this before but haven't touched NH in about 4 months and have forgotten... projections maybe? help!!!
Thanks
Sat down with a fresh pair of eyes and figured it out... Tags are now ordered by a propery on the Tags Question collection (views).. which made alot more sence in my domain than ordering by the count of children
public IList<Tag> GetTop(int numberOfTags)
{
using (ITransaction transaction = Session.BeginTransaction())
{
DetachedCriteria detachedCriteria = DetachedCriteria.For<Tag>()
.CreateCriteria<Tag>(x => x.Questions)
.AddOrder<Question>(x => x.Views, Order.Desc)
.SetMaxResults(numberOfTags)
.SetProjection(Projections.Distinct(Projections.Id()));
IList<Tag> tags = Session.CreateCriteria<Tag>()
.SetFetchMode<Tag>(x => x.Questions,FetchMode.Join)
.Add(LambdaSubquery.Property<Tag>(x => x.Id).In(detachedCriteria))
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.List<Tag>();
transaction.Commit();
return tags;
}
}
Try:
var tags = Session.CreateCriteria(typeof(Tag))
.AddOrder(Order.Asc("Tag.Question.Id")
.List<Tag>();
// If that does not work, try:
var tags = Session.CreateCriteria(typeof(Tag))
.CreateCriteria("Question", "TagQuestion", JoinType.InnerJoin)
.AddOrder(Order.Asc("TagQuestion.Id")
.List<Tag>();
Ordering on joined columns.
Ordering the query criteria.
Edit: Unless you're deciding against it or your already comfortable with the Criteria API, you should take a look at either HQL or NHibernate.Linq:
var tags = Session.Linq<Tag>()
.OrderBy(tag => tag.Question.Id)
.ToList();
Linq to NHibernate: a vast improvement.