Asp.net / entityframework - почему мой пул приложений дает сбой?

Я пытаюсь добавить в свой API новый метод.

Цель метода - вернуть список Partenaires, имеющих данный Prestation в своих предустановках.

Когда я вызываю метод с помощью запроса GET, пул приложений моего API дает сбой. В журналах событий у меня есть предупреждение под названием Microsoft-Windows-WAS, и связанная ошибка:

A process serving application pool 'UphairApi2' suffered a fatal communication error with the Windows Process Activation Service. The process id was '3960'. The data field contains the error number.

И инструмент разработчика сети говорит, что не смог загрузить данные ответа.

Failed to load response data

Когда я возвращаю return db.Partenaires.Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value)).ToString();, вот ответный запрос:

"SELECT\r\nExtent1.IdPartenaire, \r\nExtent1.FirstName, \r\nExtent1.LastName, \r\nExtent1.Email, \r\nExtent1.Password, \r\nExtent1.PasswordSalt, \r\nExtent1.Type, \r\nExtent1.Pays, \r\nExtent1.Ville, \r\nExtent1.CodePostale, \r\nExtent1.Adresse, \r\nExtent1.Lat, \r\nExtent1.Lng, \r\nExtent1.ImageUrl, \r\nExtent1.CouvertureUrl, \r\nExtent1.DateNaissance, \r\nExtent1.ADomicile, \r\nExtent1.SeDeplace, \r\nExtent1.DateAjout, \r\nExtent1.AdresseComplement, \r\nExtent1.TelMobile, \r\nExtent1.ValidationAutomatique, \r\nExtent1.NotifEmailMessage, \r\nExtent1.NotifEmailReservation, \r\nExtent1.NotifEmailPaiement, \r\nExtent1.NotifEmailNewsletter, \r\nExtent1.NotifSmsMessage, \r\nExtent1.NotifSmsReservation, \r\nExtent1.IdUserMango, \r\nExtent1.Iban, \r\nExtent1.TitulaireCompte, \r\nExtent1.IdWallet, \r\nExtent1.IdAccount, \r\nExtent1.Valide, \r\nExtent1.Son, \r\nExtent1.Push, \r\nExtent1.IdPhone\r\nFROM Partenaire AS Extent1\r\n WHERE EXISTS(SELECT\r\n1 AS C1\r\nFROM PartenairePrestation AS Extent2 INNER JOIN Prestation AS Extent3 ON Extent2.IdPrestation = Extent3.IdPrestation\r\n WHERE (Extent1.IdPartenaire = Extent2.IdPartenaire) AND ((Extent3.NomPrestation = @p__linq__0) OR ((Extent3.NomPrestation IS NULL) AND (@p__linq__0 IS NULL))))"

И эквивалент для Mysql Workbench:

SELECT Extent1.IdPartenaire, Extent1.FirstName, Extent1.LastName, Extent1.Email, Extent1.Password, Extent1.PasswordSalt, Extent1.Type, Extent1.Pays, Extent1.Ville, Extent1.CodePostale, Extent1.Adresse, Extent1.Lat, Extent1.Lng, Extent1.ImageUrl, Extent1.CouvertureUrl, Extent1.DateNaissance, Extent1.ADomicile, Extent1.SeDeplace, Extent1.DateAjout, Extent1.AdresseComplement, Extent1.TelMobile, Extent1.ValidationAutomatique, Extent1.NotifEmailMessage, Extent1.NotifEmailReservation, Extent1.NotifEmailPaiement, Extent1.NotifEmailNewsletter, Extent1.NotifSmsMessage, Extent1.NotifSmsReservation, Extent1.IdUserMango, Extent1.Iban, Extent1.TitulaireCompte, Extent1.IdWallet, Extent1.IdAccount, Extent1.Valide, Extent1.Son, Extent1.Push, Extent1.IdPhone FROM Partenaire AS Extent1 WHERE EXISTS(SELECT 1 AS C1 FROM PartenairePrestation AS Extent2 INNER JOIN Prestation AS Extent3 ON Extent2.IdPrestation = Extent3.IdPrestation WHERE (Extent1.IdPartenaire = Extent2.IdPartenaire) AND ((Extent3.NomPrestation = 'Barbe')))

Я протестировал этот запрос в MysqlWorkbench, и набор данных был хорошо возвращен.

Вот мой метод:

// GET: api/Partenaires_prestations
        [Authorize]
        [Route("api/Partenaires_prestations")]
        public List<PartenaireMapItem> GetPartenairesWithPrestations() {

            Random rnd = new Random();

            var queryString = Request.GetQueryNameValuePairs();

            var prestation = queryString.FirstOrDefault();

            return db.Partenaires.Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value))
                .ToList()
                .Select(p => new PartenaireMapItem {
                    IdPartenaire = p.IdPartenaire,
                    FirstName = p.FirstName,
                    LastName = p.LastName,
                    NomComplet = p.LastName.Substring(0,1).ToUpper() + ". " + p.FirstName,
                    Type = p.Type,
                    DureeMin = 50,
                    Lat = p.Lat,
                    Lng = p.Lng,
                    ImageUrl = p.ImageUrl,
                    SeDeplace = p.SeDeplace,
                    ADomicile = p.ADomicile,

                    Notes = p.NoteClientPartenaires,
                    Prestations = p.PartenairePrestations.Select(y => y.Prestation.NomPrestation).ToList();
                }).ToList();
}

Что я делаю не так ?

Любая помощь будет принята с благодарностью, так как я не смог найти другую связанную тему в Интернете.

Есть подсказка? Я совсем заблудился ..

Pierrick Martellière 11.08.2018 15:42
2
1
85
1

Ответы 1

Возможно, вам потребуется отладить API и указать более подробную информацию, чтобы помочь сузить причину. Я вижу пару вещей:

var prestation = queryString.FirstOrDefault();
// Handle when prestation comes back #null. Is that valid?

var results = db.Partenaires.Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value))
//                .ToList() // Avoid .ToList() here... Select the entity properties you need.
    .Select(p => new PartenaireMapItem {
        IdPartenaire = p.IdPartenaire,
        FirstName = p.FirstName,
        LastName = p.LastName,
        // NomComplet = p.LastName.Substring(0,1).ToUpper() + ". " + p.FirstName, // Remove. Make this a computed property in your view model.
        Type = p.Type,
        // DureeMin = 50, // Can remove, can be a computed property.
        Lat = p.Lat,
        Lng = p.Lng,
        ImageUrl = p.ImageUrl,
        SeDeplace = p.SeDeplace, // Ok if a String/value. 
        ADomicile = p.ADomicile, // Ok if a String/value.

        Notes = p.NoteClientPartenaires, // Ok if a String/value.
        Prestations = p.PartenairePrestations.Select(y => y.Prestation.NomPrestation).ToList(); // Assuming this is retrieving the names of presentations. List<string>.
    }).ToList();

return results;

Ранний .ToList () требовался, потому что вы пытались вычислить значения (NameComplet) в выражении Linq, которое обычно передавалось бы в EF, что ваш провайдер БД не мог понять. Для повышения эффективности выберите только сопоставленные свойства и вместо этого измените все вычисленные значения на свойства только для чтения в вашей модели представления. (PartenaireMapItem)

private string _nomComplet = null;
public string NomComplet
{ 
    get { return _nomComplet ?? (_nomComplet = LastName.Substring(0,1).ToUpper() + ". " + FirstName); }
}

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

Остальные свойства должны быть в порядке, если предположить, что SeDeclace / ADomicile являются строковыми значениями, а не дочерними объектами. То же самое и со списком Prestations. Список строк для имен Prestation подойдет.

Другое небольшое изменение, которое я сделал, заключалось в том, чтобы получить модели представления в переменной для проверки перед возвратом. Это лучше облегчает использование точки останова для проверки результатов перед возвратом. Отсюда определите, возвращается ли какая-либо ошибка из вычисления результатов или чего-то еще, например, сериализации полученных моделей представления обратно клиенту.

Другие вопросы по теме