Zapytanie LINQ

0

Witajcie, mam do napisania zapytanie , które ma wyświetlić unikatowe rekordy , które pojawiają się w bazie przynajmniej raz. Napisałem zapytanie do SQLa - powinno ono wyglądać tak:

SELECT a.Name, a.ProductID
	FROM Production.Product a
    INNER JOIN Production.ProductReview b
    ON a.ProductID =  b.ProductID
	group by a.Name , a.ProductID 
	having count(a.ProductID) >=1

Chciałbym powyższe zapytanie przetworzyć na LINQ Udało mi się napisać coś takiego:

 var query = from product in db.ProductReviews
                            join productreviews in db.ProductReviews
                            on product.ProductID equals productreviews.ProductID
                            group product by product.ProductID  into grp
                            where grp.Count() >= 1
                            select new { grp };

Niestety nie do końca działa to tak jak powinno. Ogólnie chciałbym, żeby zapytanie przypisać do List<Product> a nie do vara, ewentualnie zostawić już tego vara, ale wyświetlić wszystkie pola z tabeli Product a nie tylko ProductID. Mi już kończą się pomysły , z góry dzięki za pomoc ! W załączeniu schemat tych dwóch tabeli.

0

Ten Twój var to w tym miejscu najprawdopodobniej IGrouping<int, Product> i generalnie możesz go traktować jako IEnumerable<Product>.

0

OK rzeczywiście , jak zrezygnuję z typu anonimowego i wybiorę select grp to mam:

 IQueryable<IEnumerable<Product>>

I w sumie chyba mogłoby tak być. Chciałbym jednak wybrać wszystkie pola z tabeli Product a wybiera mi się tylko pole, które podlega grupowaniu, czyli ProductID. Jakiś pomysł?

2

O ile dobrze rozumiem, to potrzebujesz tam po prostu SelectMany(x => x.ToList()), ale nie wiem jak to zapisać w LINQ expression.

Tu masz przykład analogicznego problemu (spłaszczenie kolekcji po grupowaniu) w normalnym zapisie:

var members = typeof (string).GetMembers()
    .GroupBy(x => x.MemberType)
    .SelectMany(x => x.ToList());
1

sql:

GROUP BY a.Name , a.ProductID

linq:

group product by product.ProductID  into grp

Po pierwsze potrzebujesz grupować po dwóch polach, grupujesz po jednym.
Po drugie Twoim sql nie uzyskasz tego, co chcesz, więc w linq tym bardziej. Jeśli chcesz otrzymać listę produktów, które mają chociaż jedno review, to zrobisz to inaczej:

products.Where(p => p.ProductReviews.Any())

albo

from p in products
where products.ProductReviews.Any()
select p

albo - jeśli nie masz FK (schemat z bazy mówi, że masz) albo nie masz ich zamapowanych do ORM:

products.Where(p => productReviews.Any(pr => pr.ProductId == p.Id))

Z Twojego zapytania można zrobić takie rozwiązanie (czysto akademickie, bo zawierające wiele zbędnych rzeczy i tragiczne, jeśli chodzi o wydajność):

var productIds = (from product in db.ProductReviews
    join productReviews in db.ProductReviews
    on product.ProductID equals productReviews.ProductID
    group product by product.ProductID  into groupedProducts
    where groupedProducts.Count() >= 1 // IMHO zbędne, bo join productReviews nie jest left joinem, więc produkty nieposiadające review nie znajdą się w wynikach
    select groupedProducts.Key.Id
).ToList();
var productsThatHaveReview = db.Products.Where(p => productIds.Contains(p.Id)).ToList();
0

Dzięki wielkie!

1 użytkowników online, w tym zalogowanych: 0, gości: 1