Как получить более одного экземпляра уникального идентификатора с помощью linq? - PullRequest
0 голосов
/ 24 мая 2018

В моем API есть действие post, которое создает заказ на основе некоторых данных, которые он извлекает из модели представления.

Он должен иметь возможность извлекать все фильмы из таблицы «фильмов», которыепередается к нему через модель представления и создания заказа.Модель представления передает действию идентификаторы фильмов, которые необходимо извлечь.

У меня есть рабочее решение, и при предоставлении данных действия, подобных этому, оно работает:

{
     "movieIds": [34, 35],
     "customerId": 21
}

база данных:

enter image description here

Однако, когда я даю данные действия, которые содержат два или более фильма с одинаковым идентификатором, он сохраняет только один фильм.

{
     "movieIds": [34, 34],
     "customerId": 21
}

база данных:

enter image description here

После отладки кода я обнаружил, что именно этот оператор linq вызывает проблему, он только когда-либосохраняет один экземпляр фильма в «фильмы».

movies = _context.Movies.Where(m => newRental.MovieIds.Contains(m.Id)).ToList();

Кто-нибудь знает, почему это происходит?и как построить оператор linq, который позволяет сохранить несколько идентификаторов?

Ответы [ 4 ]

0 голосов
/ 24 мая 2018

Вам нужно выбрать фильмы из вашего переданного списка, а НЕ из списка фильмов в базе данных.В терминах SQL вы говорите

select * from movies where movieId in (34,34)

, что, конечно, вернет только одну строку.Вместо этого вам нужно выбрать один фильм для каждой записи в вашем списке.Это будет менее эффективно для длинных списков фильмов, но я предполагаю, что это вряд ли будет огромной проблемой.

movies = newRental.MovieIds
.Select(rm => _context.Movies.FirstOrDefault(m => m.Id==rm)
.Where(x => x != null) //Just make sure no entries are NULL.. optional
.ToList();

Это должно делать то, что вы хотите.

Для более запутанного, новозможно, более эффективное решение для работы с БД, вы могли бы вместо этого сделать это:

//Get list of matches from DB into a list in one hit.
var possibleMovies = _context.Movies.Where(m=>newRental.MovieIds.Contains(m.Id)).ToList();

//Match up entries in request to DB entries.
movies = newRental.MovieIds
    .Select(rm => possibleMovies.FirstOrDefault(m => m.Id==rm))
    .Where(x => x != null) //Just make sure no entries are NULL.. optional
    .ToList();

И это приведет к извлечению всех фильмов одним оператором, а затем использовать этот список для сопоставления запрошенного списка.Вы почти наверняка могли бы сделать это более кратко, но это ясно и очевидно - если вы посмотрите на это через 2 месяца, это вас не смущает .....:)

0 голосов
/ 24 мая 2018

Редактировать: не используйте это!Как правильно указал ксанатос, это антипаттерн.Я оставлю все как есть в учебных целях!

Эта строка кода возвращает только один элемент, поскольку в _context.Movies по сути только один фильм с сохраненным идентификатором 34.Я бы изменил строку на:

movies = newRental.MovieIds.Select(movieId => _context.Movies.SingleOrDefault(m => m.Id == movieId)).ToList();

Таким образом, вы получаете результат за каждую новую аренду, независимо от того, хранится она только один раз.

0 голосов
/ 24 мая 2018

Вы можете попробовать ниже, может это вам поможет

я думаю newRental.MovieIds - это массив, который содержит список MovieIds

для конкретного custmore

movies = _context.Movies
                 .Where(m => newRental.MovieIds.Contains(m.Movie_Id) && m.customerId==21)
                 .ToList();

Только для newRental.customerId

movies = _context.Movies
                 .Where(m => newRental.MovieIds.Contains(m.Movie_Id) && newRental.customerId.contains(m.Customer_Id ))
                 .ToList();
0 голосов
/ 24 мая 2018

Если вы думаете в терминах SQL, то, что вы спрашиваете, довольно сложно (не слишком много, но, вероятно, невозможно для преобразователя LINQ Entity Framework LINQ в SQL).

Самое простое решение - умножить строки после запроса, на стороне C #.

var movies = _context.Movies.Where(m => newRental.MovieIds.Contains(m.Id)).ToList();

var movies2 = (from x in newRental.MovieIds
               join y in movies on x equals y.Id
               select y).ToList();

Мы join ("внутренний") newRental.MovieIds на movies.Таким образом, строки «умножаются», когда это необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...