Ответ 1
Если вы хотите получить только два поля, тогда вы должны спроектировать свою сущность до того, как запрос будет выполнен (и в этом случае запрос будет выполнен, когда вы вызываете FirstOrDefault
). Используйте оператор Select
для проецирования на анонимный объект с обязательными полями:
var user = context.DbUsers
.Where(u => u.u_LoginName == id)
.Select(u => new { u.u_Name, u.u_Email })
.FirstOrDefault(); // query is executed here
string name = user.u_Name; // user is anonymous object
string email = user.u_Email;
Это будет генерировать SQL как:
SELECT TOP 1 u_Name, u_Email FROM DbUsers
WHERE u_LoginName = @id
Во втором случае вы выполняете проецирование до того, как запрос будет выполнен (т.е. начато перечисление). Поэтому загружаются только требуемые поля. Но запрос будет немного другим (без TOP 1
). На самом деле, если вы преобразуете второй подход к синтаксису лямбда, он будет почти таким же:
var query = context.DbUsers
.Where(u => u.u_LoginName == id)
.Select(u => new { u.u_Name, u.u_Email });
// query is defined but not executed yet
foreach (var user in query) // executed now
{
//Stuff Here
}
И просто чтобы показать полную картину, без проекции вы получите все поля первого найденного пользователя:
DbUsers user = context.DbUsers
.Where(u => u.u_LoginName == id)
.FirstOrDefault(); // query is executed here
string name = user.u_Name; // user is DbUsers entity with all fields mapped
string email = user.u_Email;
В этом случае пользовательский объект не проецируется до выполнения запроса, и вы получите все поля пользователя, загруженные из базы данных и сопоставленные с пользовательским объектом:
SELECT TOP 1 u_LoginName, u_Name, u_Email /* etc */ FROM DbUsers
WHERE u_LoginName = @id