#c# #linq #asp.net-core #entity-framework-core
Вопрос:
У меня есть таблица под названием User
, содержащая 3 внешних ключа CountryID
, NationalityID
и EducationID
Пользователь может обновить любой из этих внешних ключей, и конечная точка должна вернуть обновленную сущность пользователя с подробными сведениями о свойстве навигации.
Поэтому, чтобы добиться этого, я сделал это, как показано ниже
var user= await _dbContext.Users
.Include(x => x.Country)
.Include(x => x.Nationality)
.Include(x => x.Education)
.Where(P => P.userID == request.userId)
.AsTracking()
.FirstOrDefaultAsync();
Затем, если пользователь хочет обновить, я это сделаю
user.CountryID= request.CountryID;
user.NationalityID= request.NationalityID;
await _dbContext.SaveChangesAsync();
var userDTO = _mapper.Map<UpdateUserResponseDTO>(user);
Проблема в том, что в ответе JSON данные о стране и национальности, такие как их имена и другие данные, возвращаются в виде null
Что я сделал, чтобы исправить это, так это добавил
_dbContext.Entry(user).Reference(x => x.Country).Load();
_dbContext.Entry(user).Reference(x => x.Nationality).Load();
_dbContext.Entry(user).Reference(x => x.Education).Load();
await _dbContext.SaveChangesAsync();
Но не уверен, каково влияние использования load
или как efficient
это происходит?
и почему asTracking
не отслеживаются изменения, внесенные в правила навигации?
И является ли использование Load()
более эффективным, чем повторная загрузка сущности пользователя после ее обновления? нравится делать
var user= await _dbContext.Users
.Include(x => x.Country)
.Include(x => x.Nationality)
.Include(x => x.Education)
.Where(P => P.userID == request.userId)
.FirstOrDefaultAsync();
Комментарии:
1. Конечно, последний будет быстрее, так как для него требуется всего одна поездка на север. Для каждого груза вам нужна специальная поездка.
2. нет ли решения этой проблемы с использованием теста?
3. Лучшее — это враг хорошего. Вы должны быть счастливы, если все работает должным образом, и не пытаться все испортить.
4. Этого недостаточно, если все работает только из-за качества и эффективности кода.
5. Когда вы выполняете сопоставление, вы можете обновить навигационное свойство с фактическими значениями новой связи. Поэтому сопоставьте User.Nationality с новым экземпляром Nationality, который вы устанавливаете. Проблема в том, что, как только вы обновите этот идентификатор, ему потребуется загрузить его запись в память, для чего в какой-то момент потребуется еще один вызов бд, если это навигационное свойство важно.
Ответ №1:
Обязательно добавьте виртуальное ключевое слово в свой контекстный класс перед любым свойством набора данных, чтобы оно было таким
public virtual DbSet<type> propname {get;set;}
А также добавьте виртуальное ключевое слово перед свойствами навигации в классах вашего домена, чтобы это было так
public class User
{
public virtual Country Country {get;set;}
}
public class Country
{
public virtual ICollection<User> Users {get;set;}
}
Эти конфигурации помогут entity framework унаследовать ваши свойства навигации и применить к ним отложенную загрузку
Комментарии:
1. Таким образом, вам больше не нужно вызывать методы загрузки. Вы также можете попробовать способ отслеживания по умолчанию, изменив статус записи на измененный после обновления идентификаторов страны и национальности пользователя
2. Например, dbcontext. Запись(объект пользователя ). Государство=государство-субъект. Модифицированный