TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2941 2.41K
День 2442. #ЗаметкиНаПолях
Используем Хранимые Процедуры в EF Core. Продолжение

Начало

2. Функция, возвращающая таблицу
Функции могут возвращать целые наборы результатов:
CREATE OR REPLACE FUNCTION 
tt.customer_order_summary(customer_id uuid)
RETURNS TABLE (
order_id uuid,
created_at timestamptz,
total numeric,
currency text,
qty numeric
)
LANGUAGE sql
AS $$
SELECT
o.id, o.created_at, o.total, o.currency,
COALESCE(SUM(oi.qty), 0) AS qty
FROM tt.orders o
LEFT JOIN tt.order_items oi ON oi.order_id = o.id
WHERE o.customer_id = customer_id
GROUP BY o.id, o.created_at, o.total, o.currency
ORDER BY o.created_at DESC
$$;

Эта функция объединяет заказы с их товарами, суммирует количество и возвращает несколько строк. Вы можете написать это на LINQ, но SQL понятнее, и вы можете протестировать его непосредственно в инструменте для работы с БД. Чтобы использовать её из C#, создайте DTO, соответствующий выходным данным функции:
public class OrderSummaryDto
{
public Guid OrderId { get; set; }
public DateTime CreatedAt { get; set; }
public decimal Total { get; set; }
public string Currency { get; set; }
public int Quantity { get; set; }
}

Затем запросите функцию, как и любую другую таблицу:
var orders = 
await dbContext.Database
.SqlQuery<OrderSummaryDto>(
$"""
SELECT order_id AS OrderId, created_at AS CreatedAt, total AS Total, currency AS Currency, qty AS Quantity
FROM tt.customer_order_summary({customerId})
""")
.ToListAsync();

Ключевым моментом является сопоставление имён столбцов со свойствами DTO с помощью алиасов. EF Core обрабатывает всё остальное автоматически.

Это простой случай без объединений, но вы можете использовать этот шаблон и в более сложных запросах. Однако вам придётся вручную проецировать данные в DTO, поскольку EF Core не может преобразовать объединения в чистом SQL в графы сущностей. Обычно вы в любом случае возвращаете плоскую структуру из функций, а затем при необходимости преобразуете её в более сложные модели на C#.

Понимание функций и процедур PostgreSQL
PostgreSQL различает функции и процедуры:
- Функции предназначены для возврата значений. Они могут возвращать скалярные значения, таблицы или даже сложные JSON-объекты. Они вызываются внутри транзакции с помощью SELECT и могут использоваться в запросах, предложениях WHERE, объединениях и других контекстах запросов.
- Процедуры предназначены для побочных эффектов. Они не возвращают значения напрямую, но могут изменять данные и иметь OUT-параметры. Вызываются с помощью CALL и идеально подходят для сложных операций, требующих явного управления транзакциями или выполнения нескольких связанных обновлений.

Используйте функции, когда нужно вернуть данные, используйте процедуры, когда нужно что-то изменить.

Окончание следует…

Источник:
https://www.milanjovanovic.tech/blog/using-stored-procedures-and-functions-with-ef-core-and-postgresql
  • 👍 9
More from @netdeveloperdiary
  1. Oct 1, 2026Post #3357
  2. Sep 30, 2026Post #3356
  3. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  4. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  5. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
  6. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →