Почему я получаю здесь имя специальности как нулевое?

Я работаю с ASP.NET Core и Entity Framework, и когда я запрашиваю этот контроллер, я получаю это.

Проблема использования метода FromSql заключается в том, что он возвращает SpecialityName как нулевое значение, когда тот же запрос на SQL Server возвращает фактическое значение SpecialityName.

Вот что я делаю:

public IActionResult Index() 
{
    var list = _context.Doctors
                       .FromSql($"select Id, FirstName, LastName,Doctors.SpecialityId , Email , SpecialityName from Doctors join Specialities on Doctors.SpecialityId = Specialities.SpecialityId")
                       .ToList(); 
    return Json(list); 
} 

Это часть результата:

{
    "id": 3,
    "firstName": "Hatem",
    "lastName": "Aiman",
    "email": "[email protected]",
    "specialityId": 1,
    "speciality": null
}

Вот мои модели и DbContext:

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    public DbSet<Doctor> Doctors { get; set; }
    public DbSet<Speciality> Specialities { get; set; }  
}

public class Doctor
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }

    public int SpecialityId { get; set; }
    public Speciality speciality { get; set; }
}

public class Speciality
{
    public int SpecialityId { get; set; }
    public string SpecialityName { get; set; }

    public ICollection<Doctor> Doctor { get; set; }
}

Я не мог не заметить, что speciality — единственный столбец, который называется по-другому (specialityName). Рассматривали ли вы возможность сделать их последовательными, как и все остальные? Почему суффикс Name стоит в одном месте, а в другом нет? Не знаю, решит ли это проблему (EF не использую), но это конечно более разумно.

testing-for-ya 21.06.2024 01:46

Нет, это был не тот случай, но я только что опубликовал свое исправление, спасибо.

Hatem Aiman 21.06.2024 01:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я использовал LINQ, и он работал нормально

public IActionResult Index()
{
    var list = from doctor in _context.Doctors
               join speciality in _context.Specialities
               on doctor.SpecialityId equals speciality.SpecialityId
               select new
               {
                   doctor.Id,
                   doctor.FirstName,
                   doctor.LastName,
                   doctor.SpecialityId,
                   doctor.Email,
                   speciality.SpecialityName
               };

    return Json(list);
}
Ответ принят как подходящий

Причина, по которой вы не получили специальность, заключается в том, что вы пытались использовать оператор SQL для получения названия специальности, но использовали DbSet<Doctor>.FromSql(), который используется для извлечения объектов «Доктор» с использованием настроенного SQL. У доктора есть ссылка на сущность специальности, но при использовании FromSql() он не знает, нужно ли загружать специальность. В 99,5% случаев вам никогда не придется использовать FromSql. Тот же результат был бы:

var doctors = _context.Doctors
    .ToList();

Если вам нужна специализированная сущность:

var doctors = _context.Doctors
    .Include(x => x.Specialty)
    .ToList();

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

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

var list = from doctor in _context.Doctors
    join speciality in _context.Specialities
        on doctor.SpecialityId equals speciality.SpecialityId
    select new
    {
        doctor.Id,
        doctor.FirstName,
        doctor.LastName,
        doctor.SpecialityId,
        doctor.Email,
        speciality.SpecialityName
    };

... можно заменить на:

var list = _context.Doctors
    .Select(d => new 
    {
        d.Id,
        d.FirstName,
        d.LastName,
        d.SpecialityId,
        d.Email,
        d.Specialty.SpecialityName // <- Access the related specialty navigation property.
    }).ToList();

Явные соединения должны быть необходимы только в том случае, если вам нужно выполнить запрос к слабосвязанным объектам, где свойства навигации не могут быть использованы из-за слабой связи, не позволяющей использовать правильные внешние ключи. EF поддерживает свойства навигации для управления связями, и их следует использовать по умолчанию везде, где это возможно. Примером использования явных объединений является денормализованная полиморфная связь, например использование OwnerType и OwnerId. Например, наличие таблицы адресов, которая может относиться к нескольким таблицам, определенным OwnerType, где OwnerId слабо связан с PK этой таблицы. Это несколько небрежный дизайн базы данных, которого следует избегать в пользу отдельных конкретных таблиц адресов для каждого родительского элемента или использовать таблицу соединения «многие ко многим», чтобы обеспечить правильную нормализацию этих отношений. Тем не менее, там, где вам приходится работать, можно использовать явные соединения.

Большое спасибо за этот ответ, с этим все сработало.

Hatem Aiman 23.06.2024 04:53

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

Похожие вопросы

Веб-API ASP.NET Core 8 + вызов Ajax к контроллеру: полностью отключить Cors
(C#/.NET 8.0) Почему я не могу получать, а затем отправлять данные из UdpClients, созданных и используемых в отдельных потоках?
Как я могу получить указатель на управляемую функцию для предоставления неуправляемому коду в качестве обратного вызова?
Выполнение сценария PowerShell с аргументами из кода C#
Получение сообщения с помощью Azure.Messaging.ServiceBus, отправленного с помощью Microsoft.ServiceBus.Messaging (ServiceBus.v1_1)
Передача значений нескольких элементов управления через кнопку в WinUI 3
Функции Azure не принимают значение в кодировке URL-адреса в качестве параметра запроса?
Как выбрать отдельные элементы из таблицы по переменной, а затем присоединиться к другой таблице в LINQ
Установите для свойства высоты стиля кнопки в дизайне материала в XAML значение по умолчанию
Azure SignalR: ни один из транспортных средств, поддерживаемых клиентом, не поддерживается сервером