I want to do this:
NHibernate.IQueryOver<DataAccess.Domain.Product, DataAccess.Domain.Product> query = session.QueryOver<DataAccess.Domain.Product>();
query = query.Where(x => x.Name == "X");
query = query.Take(1).Skip(3);
List<Product> results = query.List().ToList();
I cant find any help on Skip or Take. The tooltip help (yes I'm that desperate) says that Skip and Take return IQueryOver but the error message says something to the effect "Cant implicitly convert IQueryOver{T} to IQueryOver{T,T}. I don't know what IQueryOver{T,T} is. I didn't ask for one of those anyway.
Try to change your code like this:
NHibernate.IQueryOver<DataAccess.Domain.Product> query = session.QueryOver<DataAccess.Domain.Product>();
query = query.Where(x => x.Name == "X");
query = query.Take(1).Skip(3);
var results = query.List();
Or, even better:
var results = session.QueryOver<DataAccess.Domain.Product>()
.Where(x => x.Name == "X")
.Take(1)
.Skip(3)
.List();
You can check my code here downloading NHibernateQueryOver.
UPDATE:
I think you're missing something. I would suggest you to read this article which has been really helpful for me.
In the paragraph about Associations they say:
An IQueryOver has two types of interest; the root type (the type of entity that the query returns), and the type of the 'current' entity
being queried. For example, the following query uses a join to create
a sub-QueryOver (analagous to creating sub-criteria in the ICriteria
API):
IQueryOver<Cat,Kitten> catQuery =
session.QueryOver<Cat>()
.JoinQueryOver(c => c.Kittens)
.Where(k => k.Name == "Tiddles");
The JoinQueryOver returns a new instance of the IQueryOver than has
its root at the Kittens collection. The default type for restrictions
is now Kitten (restricting on the name 'Tiddles' in the above
example), while calling .List() will return an IList. The type
IQueryOver inherits from IQueryOver.
This is what I do when I want to build multiple filter:
Domain.OrderAddress addressDestination = null;
Domain.Customer customer = null;
Domain.TermsConditionsOfSale termsConditionsOfSale = null;
ICriterion filter1 = Restrictions.Where<Domain.Order>(t => t.Company == "MYCOMPANY");
ICriterion filter2 = Restrictions.Where<Domain.Order>(t => t.WareHouseDelivery == "DEPXX");
ICriterion filter3 = Restrictions.Where<Domain.Order>(t => t.Status == "X");
ICriterion filter4 = Restrictions.Where(() => addressDestination.AddressType == "99");
ICriterion filter5 = Restrictions.Where(() => addressDestination.Province.IsIn(new string[] { "AA", "BB", "CC" }));
ICriterion filter6 = Restrictions.Where(() => termsConditionsOfSale.ReturnedGoodsCode != "01");
var ordersForProvinces = session.QueryOver<Domain.Order>()
.Inner.JoinAlias(t => t.OrderAddresses, () => addressDestination)
.Inner.JoinAlias(t => t.Customer, () => customer)
.Left.JoinAlias(t => t.TermsConditionsOfSale, () => termsConditionsOfSale);
ordersForProvinces
.Where(filter1)
.And(filter2)
.And(filter3)
.And(filter4)
.And(filter5)
.And(filter6);
var Results = ordersForProvinces.Skip(50).Take(20).List();
UPDATE-UPDATE:
NHibernate.IQueryOver<Domain.Person> person = session.QueryOver<Domain.Person>();
var myList = DoSomething(person);
Method:
private static IList<Domain.Person> DoSomething(NHibernate.IQueryOver<Domain.Person> persons)
{
ICriterion filter1 = Restrictions.Where<Domain.Person>(t => t.CompanyName.IsLike("Customer%"));
persons.RootCriteria.Add(filter1);
var x = persons.Skip(1).Take(3).List();
return (x);
}
Related
Why does this work:
var ret = Session.Query<ListingEvent>()
.TransformWith<ListingEventProfileTransformer, ListingEventDto>()
.ToList();
var ret2 = ret.Where(x => x.EventInstance.Slug == slug);
return ret2;
but this does not:
var ret = Session.Query<ListingEvent>()
.TransformWith<ListingEventProfileTransformer, ListingEventDto>()
.Where(x => x.EventInstance.Slug == slug);
return ret;
Obviously the 1st one is no good as it needs to enumerate the collection before adding my predicate.
Surely they should both work?!
The second query is still at an IQueryable, so nothing is executed until you force the results to come back. Try this:
var ret = Session.Query<ListingEvent>()
.TransformWith<ListingEventProfileTransformer, ListingEventDto>()
.Where(x => x.EventInstance.Slug == slug)
.ToList(); // Force the results to come back
return ret;
I have a Class A that have a class B List ...
So, with QueryOver I have :
ClassB lb = null;
var result = session.QueryOver<ClassA>
.JoinAlias(x => x.ListB, () => lb, JoinType.LeftOuterJoin)
.Where(() => lb.Property == 1)
.List<ClassA>();
How Can I do that using Nhibernate Query<> ?
Thanks
Paul
Assuming what you want to do is get a list of ClassA having at least one ClassB with Property == 1:
var result = session.Query<ClassA>()
.Where(a => a.ListB.Any(b => b.Property == 1))
.ToList();
This wouldn't be an outer join, though. You might emulate that by adding || !a.ListB.Any().
I have the following Entity Framework 4.1 entities and relationships
Concert ConcertId, AdministratorUserId, Name, IsDeleted
Booking
BookingId, ConcertId, UserId, IsDeleted
UserId, UserId, Name, IsDeleted
Relationships
Concert 1.....M Booking 1....1 User
Now I am trying to select all the Concerts for a particular AdminstratorUserId but also include all the Bookings for each Concert and also the User details for each booking. I would also like to apply a filter where IsDeleted == false for each Concert, Booking and User. I Would like to return a List of Concerts which have their Booking and User details maintained as navigational properties.
In SQL, this is what I am trying to achieve:
SELECT *
FROM concert c, booking b, user u
WHERE c.ConcertId = b.ConcertId AND b.UserId = u.UserId AND c.AdministratorId = 10
AND c.IsDeleted = false AND b.IsDeleted = false AND u.IsDeleted = false
As far as I am aware, using the "Include" method to eager load, doesn't allow filtering or subqueries of the child entity it loads in; it returns all records for that join, so I tried to use an anonymous projection as follows:
int adminId = 10;
var concerts = _context.Concerts
.Where(p => p.AdministratorId == adminId && p.IsDeleted == false)
.Select(p => new {
Concerts = p,
Bookings = p.Bookings
.Where(q => q.IsDeleted == false && q.User.IsDeleted == false)
.Select(r => new {
Bookings = r,
User = r.User
})
.AsEnumerable()
.Select(q => q.Bookings)
})
.AsEnumerable()
.Select(p => p.Concerts)
.ToList();
However, this is still returning all records and not filtering out the ones where IsDeleted = true. Anyone have any ideas, or suggestions how I can clean up this monstrous query?
I have also tried a method similar to this (http://blogs.msdn.com/b/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx), which again fails (returns all bookings even deleted ones):
var concertsQuery = (ObjectQuery<Concert>)_context.Concerts
.Where(p => p.UserId == userId
&& p.IsDeleted == false
&& p.Bookings.Any(q => q.IsDeleted == false && q.User.IsDeleted == false)
);
var concerts = concertsQuery.Include("Bookings").Include("Bookings.User").ToList();
Get rid of those AsEnumerable they will turn your query to linq-to-objects:
var concerts = _context.Concerts
.Where(p => p.AdministratorId == adminId && p.IsDeleted == false)
.Select(p => new {
Concerts = p,
Bookings = p.Bookings
.Where(q => q.IsDeleted == false && q.User.IsDeleted == false)
.Select(r => new {
Bookings = r,
User = r.User
})
})
.ToList();
So, the way I've managed to resolve this issue is by running the LINQ query as per Ladislav's answer, but then using the anonymous object to re-attach the individual objects to their correct relational properties as below:
var concertResult = new List<Concert>();
foreach (var concertObject in concerts)
{
var concert = concertObject.Concert;
foreach (var bookingObject in concertObject.Bookings)
{
var booking = bookingObject.Booking;
booking.User = bookingObject.User;
concert.Bookings.Add(booking);
}
concertResult.Add(concert);
}
I want to get an object from my database but only populate it with the unique id identifier. I want all other fields to be null...any ideas on how to approach this????
Using NHibernate Linq provider:
Person obj = session.Query<Person>()
.Where(x => x.Id == id)
.Select(x => new Person() { Id = x.Id } )
.SingleOrDefault();
I'm using the QueryOver api that is part of NHibernate 3.x. I would like to get a row count, but the method I'm using returns all objects and then gets the count of the collection. Is there a way to just return an integer/long value of the number of rows?
I'm currently using:
_session.QueryOver<MyObject>().Future().Count()
After a bit of playing around with the api, this will do it:
_session.QueryOver<MyObject>()
.Select(Projections.RowCount())
.FutureValue<int>()
.Value
If you don't want to return it as a future, you can just get the SingleOrDefault<int>() instead.
Another method
var count = Session.QueryOver<Employer>()
.Where(x => x.EmployerIsActive)
.RowCount();
Another method:
int employerCount = session
.QueryOver<Employer>()
.Where(x => x.EmployerIsActive) // some condition if needed
.Select(Projections.Count<Employer>(x => x.EmployerId))
.SingleOrDefault<int>();
Im using like this:
public int QuantidadeTitulosEmAtraso(Sacado s)
{
TituloDesconto titulo = null;
Sacado sacado = null;
var titulos =
_session
.QueryOver<TituloDesconto>(() => titulo)
.JoinAlias(() => titulo.Sacado, () => sacado)
.Where(() => sacado.Id == s.Id)
.Where(() => titulo.Vencimento <= DateTime.Today)
.RowCount();
}