powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / LINQ to SQL: выборка из подчиненной таблицы... почему select *... ???
6 сообщений из 6, страница 1 из 1
LINQ to SQL: выборка из подчиненной таблицы... почему select *... ???
    #36655739
Alexey Trizno
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что-то я не понимаю поведение построителя запросов... пример:
Есть табличка Clients и подчиненная ей Users (связь OneToMany, Users.ClientID -> Clients.ID)
В результате такое выражение:

Код: plaintext
1.
2.
var client = Clients.Single(c => c.ID == 3);
var user = client.Users.SingleOrDefault(u => u.ID == 1); // !!!!
вызывает загрузку ВСЕЙ таблицы Users для указанного client.ID. Получаемый запрос от второй строки:

Код: plaintext
1.
2.
3.
4.
DECLARE @p0 Int =  3 

SELECT [t0].[ID], [t0].[ClientID], [t0].[CreateDate], [t0].[FullName]
FROM [dbo].[Users] AS [t0]
WHERE [t0].[ClientID] = @p0

Т.е. загружаются ВСЕ записи, вместо того чтобы выбрать одну через WHERE ClientID = @p0 and ID = @p1
Почему так? В подчиненной таблице может быть тысячи записей, и зачем их грузить все на клиента, если достаточно выбрать одну запросом?

p.s. в реальности поиск в client.Users идет не по ID, но это не меняет сути, и ID использован просто для простоты
...
Рейтинг: 0 / 0
LINQ to SQL: выборка из подчиненной таблицы... почему select *... ???
    #36656803
Фотография SanSYS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
очему - хз, даже сомневаюсь что вы правы, попробуйте использовать LinqPad

там можно увидеть сгенерированный запрос

но с др. стороны...
1. вы достали клиента
2. у клиента есть незагруженные юзеры
3. ищете юзера у экземпляра клиента
4. список юзеров у клиента - это 1 список, типа 1 объект, и инициализировать одну часть (загружать одного юзера) объекта, было бы нелогично, т.к. список должен быть отсортирован по индексу, потому собственно наверн и загружаются все юзеры
5. зато при поиске следующего юзера не будет запросов :)

советую написать так:
Код: plaintext
1.
2.
3.
var client = Clients.Single(c => c.ID == 3);
var user = Users.SingleOrDefault(u => u.ID == 1 && u.ClientID == client.ID); // !!!!


тогда точно 1 запрос = 1 запись ор нул
...
Рейтинг: 0 / 0
LINQ to SQL: выборка из подчиненной таблицы... почему select *... ???
    #36657320
Alexey Trizno
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SanSYSочему - хз, даже сомневаюсь что вы правы, попробуйте использовать LinqPad

там можно увидеть сгенерированный запрос


Естественно смотрел реально полученные запросы, от чего и тема выросла :)
Народ пишет что это нормальное поведение большинства фреймворков аля LtoS...

SanSYS
но с др. стороны...
1. вы достали клиента
2. у клиента есть незагруженные юзеры
3. ищете юзера у экземпляра клиента
4. список юзеров у клиента - это 1 список, типа 1 объект, и инициализировать одну часть (загружать одного юзера) объекта, было бы нелогично, т.к. список должен быть отсортирован по индексу, потому собственно наверн и загружаются все юзеры
5. зато при поиске следующего юзера не будет запросов :)


Если следовать идее - контексты создавать на короткое время, и как можно быстрее освобождать, то другие Users будут добываться уже в другом контексте, и сл-но опять будет вытаскиваться на клиента лишние записи.

Пример: сущность Project, у неё есть подчиненная табличка Respondents, в которой десятки тысяч записей. И получается что если мне надо выбрать нескольких респов, то я таки не могу использовать удобную запись project.Respondents.Where(r => r....), а вынужден пользовать что-то аля context.Respondents.Where(r => r.ProjectID == pId && r....).
Но чем такая запись отличается за чистого SQL? Почти ничем... получается что есть у нас DataContext, в нем есть куча таблиц, и с ними напрямую и приходится работать, всегда указывая все параметры выборки явно... теряется как-то абстракция, в бизнес-логику пролезают FK/PK ключи и т.д.

Получается что есть sql, чтобы от него абстрагироваться - применяем Linq To Sql, а потом поверх ещё какой-нибудь паттерн аля Repository, и тут наступает нирвана. Но блин, ничего ен мешает выкинуть удобный linq и оставить sql + repository, результат будет тот же, т.к. в бизнес-логике все равно надежнее с ним работать, чтобы иметь полный контроль над вытягиваемыми из базы данными.

Речь про базы с по крайней мере несколькими миллионами записей.

SanSYS
советую написать так:
Код: plaintext
1.
2.
var client = Clients.Single(c => c.ID == 3);
var user = Users.SingleOrDefault(u => u.ID == 1 && u.ClientID == client.ID); // !!!!

тогда точно 1 запрос = 1 запись ор нул

[/SRC]это понятно, можно и красивее сделать, например в Client добавить функу, типа:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
public IQuerable<User> UsersEx(MyDataContext context) 
{
    return context.Users.Where(u => u.ClientID == this.ID);
}

// теперь писать можно так
var user = client.UsersEx(context).Where(u => u.Name == "Admin");

и тогда будет что надо, один запрос на вытягивания одного юзера
но блин, это всё какие-то танцы с бубном... :)
...
Рейтинг: 0 / 0
LINQ to SQL: выборка из подчиненной таблицы... почему select *... ???
    #36676596
Фотография SanSYS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чтож, экзекьютквери вам в помощь :) приятно получать раскрытые ответы

у нас есть1 большой сайт, там юзается линку, собственно - сохраняе 1 датаконтекст на протяжении всего запроса, это оказалось производительнее чем создавать новые, имхо, но если выборки в каждом запросе не накладные, в противном случае - юзаем новые экземпляры
...
Рейтинг: 0 / 0
LINQ to SQL: выборка из подчиненной таблицы... почему select *... ???
    #36676747
Alexey Trizno
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SanSYSчтож, экзекьютквери вам в помощь :) приятно получать раскрытые ответы

у нас есть1 большой сайт, там юзается линку, собственно - сохраняе 1 датаконтекст на протяжении всего запроса, это оказалось производительнее чем создавать новые, имхо, но если выборки в каждом запросе не накладные, в противном случае - юзаем новые экземпляры

С ExecuteQuery тоже обнаружились проблемы :)
http://www.sql.ru/forum/actualthread.aspx?tid=765340

У меня прям дар, наступать на грабли :)
...
Рейтинг: 0 / 0
LINQ to SQL: выборка из подчиненной таблицы... почему select *... ???
    #36676750
Alexey Trizno
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / LINQ to SQL: выборка из подчиненной таблицы... почему select *... ???
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]