Pour un certain temps, j'essaie de transformer ce SQL en Linq:
var directorArr = new (int, string)[] { (1, "Bebopvsky"), (2, "Tarrantino"), (3, "CubeRick") };
var actorArr = new (int, string, int)[]
{ (1, "Dat Maan",75), (2, "That Man", 28),
(3, "Dat Women", 32), (4, "That Women", 22),
(5, "Already Women", 12) };
var moviesArr = new (int, string, int, DateTime, int, int)[]
{ (1, "Platform for soul", 121, Convert.ToDateTime("2018-12-31"), 2, 9),
(2, "Full-featured access management", 42, Convert.ToDateTime("2019-01-01"), 3, 7),
(3, "Robust LDAP server for Java", 13, Convert.ToDateTime("2005-05-25"), 3, 4),
(4, "Man of Rain", 114, Convert.ToDateTime("2004-07-21"), 1, 10),
(5, "Man of Arms", 152, Convert.ToDateTime("2003-02-17"), 1, 9),
(6, "Man of War", 93, Convert.ToDateTime("2017-07-05"), 2, 8),
(7, "Man of Legs", 33, Convert.ToDateTime("2018-11-11"), 1, 9),
(8, "Mof", 55, Convert.ToDateTime("2015-11-11"), 2, 8) };
var movieActorArr = new (int, int)[]
{ (1,1), (1,3), (1,4), (1,5),
(2,1), (2,5),
(3,4),
(4,1), (4,2), (4,3), (4,4),
(5,1), (5,2), (5,3), (5,4), (5,5),
(6,1), (6,2), (6,3),
(7,2), (7,4), (7,5),
(8,1), (8,4) };
3 Réponses :
Si vous avez besoin d'obtenir un nom d'administrateur, ce qui a dirigé 2 films ou plus de plus de 60 minutes dans chacun desquels 3 à 7 acteurs ont participé (comme vous l'avez dit dans votre commentaire), essayez ceci:
// use group join to get movies with duration > 60 min
var filteredMovies =
from d in directors
join m in movies.Where(x => x.DurationMinutes >= 60 && x.ReleaseDate <= new DateTime(2015, 12, 31) && x.Rating >= 9)
on d.Id equals m.DirectorId into groupMovies
let moviesCountForEachDirector = groupMovies.Count()
where moviesCountForEachDirector > 1
select groupMovies;
// use group join to get movies with actors from 3 to 7
var moviesWithActors =
from m in filteredMovies.SelectMany(x => x)
join ma in movieActor on m.MovieId equals ma.MovieId into groupJoin
let actorsInEachMovieCount = groupJoin.Count()
where actorsInEachMovieCount > 2 && actorsInEachMovieCount < 8
select new
{
MovieId = m.MovieId,
};
// the rest of query
var query =
from d in directors
join m in movies on d.Id equals m.DirectorId
join ma in moviesWithActors on m.MovieId equals ma.MovieId
group d by d.Id into gr
select new { DirectorName = gr.First().Name };
Enfin, je suis venu avec une solution.
Tout d'abord, j'ai changé la requête SQL (avec une aide supplémentaire): puis dans l'image modyfied linq requête. P> var query4 = (from x in
(from d in directors
join m in movies2
on d.Id equals m.DirectorId
join ma in movieActors
on m.Id equals ma.MovieId
where m.ReleaseDate <= Convert.ToDateTime("2005-12-31")
where m.Rating >= 9
where m.DurationMinutes >= 60
group d by new { d.Name, m.Id } into res
where res.Count() >= 3
where res.Count() <= 7
select res)
group x by x.Key.Name into fin
where fin.Count() >= 2
select fin)
;
Il me défle toujours, que si les gens ont une exigence dont ils ont besoin de résoudre à l'aide de Linq, ils ne nous donnent pas la nécessité, mais traduisent d'abord l'exigence dans SQL et nous donner le SQL au lieu de l'exigence.
Il me semble que vous souhaitez une déclaration LINQ qui renvoie ce qui suit: P>
Donnez-moi tous les noms des réalisateurs qui ont dirigé des films sur ou avant une date code> code>, avec une note supérieure ou égale qu'un certain numéro de notation, pour au moins 2 films plus longs d'au moins une heure, avec au moins 3 et au plus 7 acteurs p> blockQuote>
Si vous avez des relations un à plusieurs ou plusieurs à plusieurs entre tables, et que vous souhaitez "articles avec leurs nombreux sous-éléments" comme des écoles avec leurs étudiants, des clients avec leurs commandes, des commandes avec Leurs lignes de charge, vous devriez penser à utiliser Enumérable.Groupjoin P>
Si d'autre part, vous voulez que le sous-élément avec celui qu'il appartient, comme l'étudiant avec la seule et unique école qu'il fréquente, Ou la commande avec le client unique et unique qui a placé cette commande, utilisez énumérable.join p>
Dans ce cas, nous voulons des administrateurs avec ses films, nous allons donc utiliser groupjoin. P>
TimeSpan oneHour = TimeSpan.FromHours(1); var result = directors.GroupJoin(movies, director => director.Id, // from each director take the Id movie => movie.DirectorId // from each movie take the DirectorId // result selector: take every director with all his movies to make one new: (director, moviesOfThisDirector) => new { // from the director we only need his name Name = director.Name // From each of his movies we need the ReleaseDate, the Rating and the number of actors Movies = moviesOfThisDirector.Select(movie => new { ReleaseDate = movie.ReleaseDate, Rating = movie.Rating, Duration = movie.Duration, NumberOfActors = movie.GroupJoin(actors, movie => movie.Id, actor => actor.MovieId, // ResultSelector: only count all Actors in this movie (movie, actorsInThisMovie) => actorInThisMovie.Count(), }) // well, we don't want all movies, // we only want movies before a date with a high rating and a certain duration .Where(movie => movie.ReleaseDate <= myDate && movie.Rating >= myRating && movie.Duration >= oneHour), }) // we don't want all Directors, we only want those that have at least one such a movie .Where(directory => directory.Movies.Any();
Il y a une virgule manquante après move.directid code> et un extra sur deux places. Votre échantillon de code ne compilerait pas.
Vous voulez donc le nom des administrateurs qui ont dirigé 3 à 7 acteurs et avoir deux films ou plus de plus de 60 minutes?
Quel fournisseur LINQ utilisez-vous? Linq aux objets? LINQ vers l'ensemble de l'entité (et quelle version de EF si oui)? Pouvez-vous publier vos modèles C # afin qu'il soit plus facile pour nous de reproduire?
@Hogan Directors, qui a dirigé 2 films ou plus de plus de 60 minutes à chacun desquels 3 à 7 acteurs ont participé. Maintenant, im Thinkig, que ma requête SQL a également besoin de changements.
@ 42ama ouais votre SQL était faux.