I have 3 tables:
Person
Groups
PersonsGroups
I need to select all persons when they are in the group from a list
(list from few groups)
I tried to select like this:
var tdd = GS.PersonsGroups.Include("Person")
.Where(r => s.Contains(r.GroupID.Value))
.Select(c => c.Person);
But it is not Person is it PersonGroup and I don't have all Person prop
What is the right way to get it?
Thank you very much in advance
If I understand correct, you are seeking for something like this
List<int> groupIds = ...;
var query = db.Persons
.Where(p => p.PersonGroups.Any(pg => groupIds.Contains(pg.GroupID.Value));
Related
I have Questions table and List of CategoryIds. I have to get one question from each CategoryId randomly. Right now I'm doing like this:
var randomQuestions = new List<Question>();
foreach(int id in categoryIds){
randomQuestions.add(questions.Where(o => o.CategoryId== id).OrderBy(o => Guid.NewGuid()).FirstOrDefault());
}
But is there way to do it only with Linq? Thanks
This should do what you want in one query
var randomQuestions = questions
.Where(q => categoryIds.Contains(q.CategoryId))
.GroupBy(q = > q.CategoryId)
.Select(grp => grp.OrderBy(_ => Guid.NewGuid()).First())
.ToList();
That will first filter only questions in the categories you care about, then it groups on the category id and for each group it randomly picks one.
I have a table "Book" with a many-to-many relationship to "Tag" and need a distinct Book-count pr. Tag. In SQL, the query looks like this:
SELECT t.NAME,
count(DISTINCT b.BookId)
FROM _Tag t
JOIN Book.BookTag bt
ON t.Id = bt.TagId
JOIN Books b
ON b.BookId = bt.BookId
GROUP BY t.NAME
ORDER BY count(DISTINCT b.BookId) DESC;
I have fetched the tags and included the Books navigation-property and from this I should be able to get distinct BookId's pr. tagname. I want to get the result in a tuple.
So far I have tried the following:
var tagTuples = from tag in tags
join book in tags.Select(t => t.Books) on tag.Books equals book
group new {tag, book} by tag.Name
into g
select new Tuple<string, string, int>("tags", g.Key, g.Select(x => x.book).Count());
...and...
var tagTuples = tags.GroupBy(t => t.Name)
.Select(t2 => new Tuple<string, string, int>("tags", t2.Key, t2.Sum(t4 => t4.Books
.Select(b => b.BookId).Distinct().Count())))
.Where(t3 => !string.IsNullOrWhiteSpace(t3.Item2)).Take(15);
...and my latest version:
var tagTuples =
tags.Select(t => new {t.Name, BookId = t.Books.Select(b => b.BookId)})
.GroupBy(tb => tb.Name)
.Select(tb2 => new Tuple<string, string, int>("tags", tb2.Key, tb2.Sum(tb3 => tb3.BookId.Distinct().Count())));
Nevermind the small differences in the query's - I'm only interested in a solution to the problem described above.
Frustration! It takes me 2 minutes to write an SQL query that does this and I'm pretty sure there's a simple answer, but I lack EF routine.
Thankyou for your time. :)
using(var ctx = new EntitiesContext())
{
// GROUP By name
var bookCountByTag = ctx.Tags.GroupBy(t => t.Name)
.Select(t2 => new {
// SELECT the key (tag name)
t2.Key,
// "GroupBy" has many result, so use SelectMany
Count = t2.SelectMany(t3 => t3.book)
.Distinct()
.Count()})
.ToList();
}
This is driving me mad. I thought it seemed simple enough but the below is returning a list of IEnumerable containing the entities I need, instead of just a list of entities:
db.tblPeople.Where(p => p.id == id).Select(s => s.tblCars.Select(z => z.tblCarType)).ToList();
My attempt is to retrieve a list of all carType entities associated with the personId.
I assume it's something to do with the last nested select?
Do like this because you are expecting multiple records to be returned:
var result = db.tblPeople
.Where(p => p.id == id)
.Select(s => s.tblCars
.SelectMany(z => z.tblCarType)).ToList();
Use SelectMany in order to flatten IEnumerable<IEnumerable<CarType>> into IEnumerable<CarType>.
var carTypes =
db.tblPeople
.Where(p => p.id == id)
.SelectMany(s =>
s.tblCars
.Select(z => z.tblCarType))
.ToList();
This translates from
var carTypes =
(from person in tblPeople
from car in person.tblCar
from carType in car.tblCarType
where person.id == id
select carType).ToList();
This is what you want/need:
db.tblPeople.Where(p => p.id == id).SelectMany(s => s.tblCars.Select(z => z.tblCarType)).ToList();
I have a problem. I have Persons and Cats. Each Person has some Cats (there is a foreign key in Cats that points to the primary key in Persons). Each Cat has an Age. I want to select the Persons that have "Old" Cats. I want ALL the Cats of these persons, and not only the "Old" Cats.
I need to do it with the QueryOver syntax.
In T-SQL it would be something like:
SELECT P.*, C.*
FROM Persons P
LEFT JOIN Cats C
ON P.Id = C.OwnerId
WHERE EXISTS (
SELECT 1
FROM Cats C2
WHERE P.Id = C2.OwnerId AND C2.Age > 5)
I know I have to use the subqueries, and I could to easily with the "old" nhibernate syntax (the Criteria/DetachedCriteria), but I can't do it in QueryOver syntax.
I DON'T want an "IN" condition. My Primary Key is a complex key, so I can't do it with the IN.
var persons = session.QueryOver<Person>.WithSubquery.WhereExists( ??? );
Example taken from this page and adapted (tested with my own classes):
The trick seems to be using an alias.
Person personAlias = null;
IList<Person> persons =
session.QueryOver<Person>(() => personAlias).WithSubquery
.WhereExists(QueryOver.Of<Cat>()
.Where(c => c.Age > 5)
.And(c => c.Owner.Id == personAlias.Id)
.Select(c => c.Owner))
.List<Person>();
How to use Linq to select and group complex child object from a parents list.
I have an OrderList each of order object has a OrderProductVariantList(OrderLineList), and each of OrderProductVariant object has ProductVariant, and then the ProductVariant object will have a Product object which contains product information.
My goal is to select and group the most popular products from the order list.
Can anyone help me with this?
Many thanks.
Your description is hard to follow, but I think you just want to get out the Products and rank them by the number of times they occur. SelectMany will be helpful for this.
var query = orderList.SelectMany( o => o.OrderLineList )
// results in IEnumerable<OrderProductVariant>
.Select( opv => opv.ProductVariant )
.Select( pv => p.Product )
.GroupBy( p => p )
.Select( g => new {
Product = g.Key,
Count = g.Count()
});
A query is not a result. To view the result you can iterate over the query object:
foreach (var result in query) {
Console.WriteLine(result);
}
As to why query wasn't available in the watch window, I can only imagine that it either wasn't in scope yet, or it had already gone out of scope. Try putting a breakpoint on the line immediately after the line you posted where you assign to query.