Я работаю с 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; }
}
Нет, это был не тот случай, но я только что опубликовал свое исправление, спасибо.





Я использовал 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 этой таблицы. Это несколько небрежный дизайн базы данных, которого следует избегать в пользу отдельных конкретных таблиц адресов для каждого родительского элемента или использовать таблицу соединения «многие ко многим», чтобы обеспечить правильную нормализацию этих отношений. Тем не менее, там, где вам приходится работать, можно использовать явные соединения.
Большое спасибо за этот ответ, с этим все сработало.
Я не мог не заметить, что
speciality— единственный столбец, который называется по-другому (specialityName). Рассматривали ли вы возможность сделать их последовательными, как и все остальные? Почему суффиксNameстоит в одном месте, а в другом нет? Не знаю, решит ли это проблему (EF не использую), но это конечно более разумно.