Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.65/34: Рейтинг темы: голосов - 34, средняя оценка - 4.65
0 / 0 / 0
Регистрация: 11.07.2020
Сообщений: 6
.NET Core

Вывести в DataGrid выборку из нескольких таблиц

24.08.2021, 20:00. Показов 7472. Ответов 8

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Ситуация следующая. Используя Entity Framework Core методом CodeFirst создал базу данных с отношением многие ко многим.
Получилось три таблицы, например: Students, Courses и CourseStudent.
Делал запросы в Microsoft SQL Server на объединение таблиц. Все замечательно, все работает.
Но каким образом я могу объединить таблицы и вывести их в элемент WPF DataGrid?
Примерно вот так:

Программирование Иванов
Программирование Петров
Программирование Сидоров
Алгоритмитизация Зуброва
Алгоритмитизация Пушкин



Пробовал применят LINQ to Entities и так и сяк. Ничего не получается.

Это классы для примера с сайта Метанит. На основании них создавалась база данных:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Course
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Student> Students { get; set; }= new List<Student>();
}
public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Course> Courses { get; set; } = new List<Course>();
}
public class ApplicationContext : DbContext
{
    public DbSet<Course> Courses { get; set; }
    public DbSet<Student> Students { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=relationsdb;Trusted_Connection=True;");
    }
}
Спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.08.2021, 20:00
Ответы с готовыми решениями:

Как осуществить выборку из нескольких таблиц а затем вывести это в MS Word
Здравствуйте.Подскажите как осуществить выборку из нескольких таблиц а затем вывести это в ворд.проблема в том что в таблицах все поля...

Запрос на выборку из нескольких таблиц
Добрый день! Не могу совладать с запросом. Есть 3 таблицы с кучей полей, выделю только ключевые из них: Таблица Klyuch_tb ...

Запрос на выборку из нескольких таблиц
Необходимо составить запрос с использованием JOIN, по которому выводится список кандидатов и должности, на которые они претендуют. ...

8
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
24.08.2021, 22:35
Caveman, https://metanit.com/sharp/entityframework/4.4.php
https://stackoverflow.com/ques... in-winform
0
0 / 0 / 0
Регистрация: 11.07.2020
Сообщений: 6
25.08.2021, 19:13  [ТС]
AndreyVorobey,
Что касается того что по первой ссылке. Это уже пробовал много раз в различных вариациях. Я не могу вывести то что получается в WPF DataGrid. Тем более у меня нет классов промежуточных таблиц, я не могу обращаться к ним при объединении.
То что по второй ссылке, не совсем понимаю к чему это.

Еще хочу сказать, что облазил весь интернет и не нашел ответа. На этот форум обращаюсь как в последнюю инстанцию.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
25.08.2021, 22:22
Caveman, Первая ссылка про то, как писать выборку из нескольких таблиц Linq.
Вторая о том, как подключать результаты выборок, которых нет в контексте EF

Все, что Вам было нужно, это осмыслить текст и применить его.
1. Написать собственно запрос, возвращающий то, что нужно
2. По результатам запроса написать класс MyClass
3. Написать код linq "под запрос", завернув полученный результат в List<MyClass>
4. Привязать грид к полученному листу. При этом если нужно будет редактировать данные в гриде, позаботиться о том, чтобы переопределить методы для Insert/Update/Delete

Добавлено через 10 минут
По поводу приведенного Вами кода, якобы с метанита.
У вас в нем все в куче: контекст и классы модели. Возможно, в новомодном EF Core так принято, но правильно разделять их по разным юнитам. Контекст - свой класс и юнит, для каждой модели - свой класс и юнит. А все это в папке .edmx в папке Models. Вот в эту же папку Models (но не .edmx) нужно добавлять классы расширения, которых нет в контексте (так как в БД нет самих сущностей). Кроме того, рядом нужно создать один один класс - Repository, в котором будет код для манипуляции с Хранилищем (БД). Repository, как и классы расширения, в совокупности с моделями и контекстом EF, будут Вашим ORM, которым и будет пользоваться код Вашего приложения.
Для решения сабжевой задачи как раз и нужен метод репозитория и класс расширения, причем код самого репозитория будет юзать модели и контекст EF.

Добавлено через 12 минут
Поймите одну простую вещь: EF работает с сущностями базы данных: таблицами, ограничениями, View, UDF, SP и т.д. То, что есть в базе, он интерпретирует (отображает) на Модель. Но то, чего там нет, например произвольных запросов, он просто не видит и видеть не может.

Если Вам потребовался запрос из двух или более таблиц, например, для отображения в сетке, Вы должны либо написать View/UDF/SP на сервере и включить ее в Модель (как класс и метод контекста) посредством самого EF, либо ручками написать класс и метод репозитория. С точки зрения грида они будут абсолютно "равноправными". Правда, тут есть нюанс, касающийся редактирования в гриде. Полагаю, что Вы сами разберетесь что там к чему.
0
0 / 0 / 0
Регистрация: 11.07.2020
Сообщений: 6
26.08.2021, 21:04  [ТС]
Я, честно говоря, уже не первую неделю над этим бьюсь.
Давайте я попробую еще раз.
1. Создаю классы и контекст, как в первом сообщении.
2. Пробую для примера вывести студентов с их Id в DataGrid.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
 
 
            using (ApplicationContext db = new ApplicationContext())
            {
                var result = db.Students.FromSqlRaw("SELECT * FROM Students ").ToList();
                dataGrid.ItemsSource = result;      
            }
 
        }
    }
Все работает. Студенты с их Id выводятся в DataGrid. Давайте пойдем дальше. Я попробую написать код Linq и вывести в DataGrid тоже самое:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
            using (ApplicationContext db = new ApplicationContext())
            {
 
                var result = from student in db.Students
                                                      
                            select new 
                            {
                                Id=student.Id,
                                Name =student.Name,    
                            };
 
                dataGrid.ItemsSource = result;
            }
У меня на этом этапе уже ничего не работает. Не говоря уже о том, что если я пытаюсь объединить таблицы со студентами и курсами, промежуточных классов просто нет.
Пробовал создавать дополнительные классы. Ну, не знаю. Делаю что-то не так, что - понять не могу.
0
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
26.08.2021, 23:00
Caveman, а напомни, чем первый вариант с применением sql хуже, учитывая, что ты не шаришь в linq.
Во втором случае у тебя отложенное выполнение запроса, пропиши ToList() в конце, как в первом варианте.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
27.08.2021, 00:38
Простой пример:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CREATE TABLE Classes (
   C_Id INT IDENTITY(1,1) PRIMARY KEY,
   C_Name VARCHAR(MAX) NOT NULL
)
-- Таблица сферы обитания (лес, океан, горы..)
CREATE TABLE LivingArea (
   L_Id INT IDENTITY(1,1) PRIMARY KEY,
   L_Name VARCHAR(MAX) NOT NULL
)
-- Таблица животных
CREATE TABLE Animals (
   A_Id INT IDENTITY(1,1) PRIMARY KEY,
   A_C_Id INT REFERENCES Classes(C_Id)   NOT NULL,
   A_L_Id INT REFERENCES LivingArea(L_Id)   NOT NULL,
   A_Name VARCHAR(MAX) NOT NULL
)
-- Запрос на выборку животных с классом и сферой обитания
SELECT A.A_Id AS Id, A_Name AS AnimalName, C.Name AS ClassName, L.Name  AS LivingAreaName
  FROM Animals A, Classes C, LivingArea L
  WHERE A.A_C_Id = C.C_Id AND A.A_L_Id = L.L_Id
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Animal 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string ClassName { get; set; }
    public string LivingAreaName { get; set; }
}
 
public List<Animal> FetchAllAnimals(string Connstring)
{
    List<Animal> animalList = new List<Animal>();
    using (SqlConnection con = new SqlConnection(ConnString))
    {
         con.Open();
         SqlCommand comm = new SqlCommand
         (   
              "SELECT A.A_Id AS Id, A_Name AS AnimalName, C.Name AS ClassName, L.Name  AS LivingAreaName " +
              "  FROM Animals A, Classes C, LivingArea L "+
              "  WHERE A.A_C_Id = C.C_Id AND A.A_L_Id = L.L_Id "
              , con
         )
         SqlDataReader reader = comm.ExecuteReader();
         while (reader.Read())
         {
              animalList.Add(new Animal { 
                   Id = reader.GetInt(0), 
                   Name = reader.GetString(1), 
                   ClassName = reader.GetString(2), 
                   LivingAreaName = reader.GetString(3), 
              });
         }
         reader.Close();
    }
    return animalList;
}
   ...
   dataGridView1.DataSource = FetchAllAnimals(Строка подключения);
Добавлено через 15 минут
Небольшие пояснения к коду.
Класс модели может не соответствовать результатам выборки не только по именам полей, ни и их количеству и даже типам данных.
Нужное соответствие устанавливается кодом обработки записей ридера. В примере соответствия нет только по именам (кстати, алиасы выходных полей-колонок в самом запросе можно убрать т.к. в ридере используется индексатор)
Функция запускает запрос на сервер, после чего полученный набор данных "упаковывает" (мапирует) в список моделей, который в нужном месте кода кладется в грид.
Грид просто отображает содержимое этого списка.

Важно. Для того, чтобы данные можно было редактировать непосредственно в гриде, код следует "обогатить", добавив в модель айдишники классов животных и сфер обитания, которые будут использоваться при добавлении/изменении записей животных. Ну и еще кое-что сделать

Добавлено через 8 минут
Код функции можно переписать с ADO.NET на linq, но в этом случае модель либо должна строго соответствовать возвращаемому НД (имена поле и типы данных, а также их число),
либо придется написать переименования и приведения к типу полей модели в самом linq, где такая возможность имеется).
0
0 / 0 / 0
Регистрация: 11.07.2020
Сообщений: 6
30.08.2021, 20:06  [ТС]
Цитата Сообщение от AndreyVorobey Посмотреть сообщение
Во втором случае у тебя отложенное выполнение запроса, пропиши ToList() в конце, как в первом варианте.
Вы предлагаете так сделать?
C#
1
2
3
4
5
6
7
8
9
10
11
                var result = from student in db.Students
                                 
 
                             select new
                             {
                                 Id = student.Id,
                                 Name = student.Name,
 
                             };
 
                dataGrid.ItemsSource = result.ToList();
Это не работает.



Цитата Сообщение от AndreyVorobey Посмотреть сообщение
напомни, чем первый вариант с применением sql хуже, учитывая, что ты не шаришь в linq
Вот так? Допустим пытаюсь вывести в DataGrid только имена студентов:
C#
1
2
  var query = db.Students.FromSqlRaw("SELECT name FROM Students ").ToList();
                dataGrid.ItemsSource = query;
Ну, опять таки, это не работает. Про безуспешные попытки вывести объединенные таблицы снова даже писать не буду.

Добавлено через 10 минут
MsGuns, Э... Я задал вопрос в разделе ADO.Net потому что не был уверен к какой теме вопрос отнести.
Я хочу именно в EF Core либо через Linq либо через запросы SQL вывести результат в dataGrid.

Цитата Сообщение от MsGuns Посмотреть сообщение
Код функции можно переписать с ADO.NET на linq, но в этом случае модель либо должна строго соответствовать возвращаемому НД (имена поле и типы данных, а также их число),
То есть нужно создать еще один класс, который будет соответствовать запросу Linq?
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
30.08.2021, 21:35
Цитата Сообщение от Caveman Посмотреть сообщение
То есть нужно создать еще один класс, который будет соответствовать запросу Linq?
Да, конечно
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.08.2021, 21:35
Помогаю со студенческими работами здесь

Запрос на выборку из нескольких таблиц
Сразу оговорюсь - перерыл весь форум и гугл. Есть много похожего, но ничего применительно к моей ситуации. Задача - создание запроса...

Запросы на выборку с нескольких таблиц
Помогите создать следующие запросы: Создать выборку за указанный квартал по схеме код офиса - офис - сумма оплаты. Создать выборку...

Запрос на выборку из нескольких таблиц
Добрый день,ребята. Помогите пожалуйста: почему выдает пустые значения и что и где надо исправить? Через UNION данную выборку...

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

Как сделать выборку из нескольких таблиц?
всем привет, у меня такая проблемка, на страничке получаю идентификатор &quot;svetilnik&quot; (svet.php?id=23) для запроса в такую табличку...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru