Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
join в LINQ используется для объединения двух последовательностей на основе соответствия ключей. Вот краткие примеры, показывающие, как работают join в LINQ.Соединяет элементы двух коллекций, если их ключи совпадают.
var query = from user in users
join order in orders on user.Id equals order.UserId
select new { user.Name, order.OrderId };
Создает группы элементов из второй коллекции, соответствующие каждому элементу из первой коллекции.
var query = from user in users
join order in orders on user.Id equals order.UserId into userOrders
select new { user.Name, Orders = userOrders };
Возвращает все элементы из первой коллекции и соответствующие элементы из второй коллекции, если они существуют.
var query = from user in users
join order in orders on user.Id equals order.UserId into userOrders
from order in userOrders.DefaultIfEmpty()
select new { user.Name, OrderId = order?.OrderId };
Данных
var users = new List<User>
{
new User { Id = 1, Name = "Alice" },
new User { Id = 2, Name = "Bob" }
};
var orders = new List<Order>
{
new Order { OrderId = 101, UserId = 1 },
new Order { OrderId = 102, UserId = 1 },
new Order { OrderId = 103, UserId = 2 }
};
Inner Join
var query = from user in users
join order in orders on user.Id equals order.UserId
select new { user.Name, order.OrderId };
foreach (var item in query)
{
Console.WriteLine($"{item.Name} - {item.OrderId}");
}
Group Join
var query = from user in users
join order in orders on user.Id equals order.UserId into userOrders
select new { user.Name, Orders = userOrders };
foreach (var item in query)
{
Console.WriteLine($"{item.Name} has {item.Orders.Count()} orders");
}
Left Join
var query = from user in users
join order in orders on user.Id equals order.UserId into userOrders
from order in userOrders.DefaultIfEmpty()
select new { user.Name, OrderId = order?.OrderId };
foreach (var item in query)
{
Console.WriteLine($"{item.Name} - {item.OrderId}");
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤2👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2❤1
Создайте индексы на столбцах, используемых в условиях соединения (
join). CREATE INDEX idx_user_id ON Users(Id);
CREATE INDEX idx_order_user_id ON Orders(UserId);
Выбирайте только необходимые столбцы, чтобы уменьшить объем данных.
var query = from user in users
join order in orders on user.Id equals order.UserId
select new { user.Name, order.OrderId };
Отложенная загрузка загружает данные только тогда, когда они действительно нужны.
var user = context.Users.Find(userId);
context.Entry(user).Collection(u => u.Orders).Load();
Разделите сложные запросы на подзапросы для улучшения читаемости и производительности.
var userIds = users.Select(u => u.Id).ToList();
var query = from order in orders
where userIds.Contains(order.UserId)
select order;
Фильтруйте данные перед выполнением
join, чтобы уменьшить размер соединяемых таблиц. var filteredUsers = users.Where(u => u.IsActive);
var query = from user in filteredUsers
join order in orders on user.Id equals order.UserId
select new { user.Name, order.OrderId };
Используйте функции ORM, которые могут генерировать более оптимизированные SQL-запросы.
var query = context.Users
.Where(u => u.IsActive)
.SelectMany(u => u.Orders, (user, order) => new { user.Name, order.OrderId });
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2😁2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
Не является стандартным термином в ASP.NET или ASP.NET Core. Возможно, имеется в виду подход к созданию запросов или API-методов в ASP.NET Core для обработки HTTP-запросов. Рассмотрим, как создавать и обрабатывать запросы в ASP.NET Core.
Контроллеры в ASP.NET Core отвечают за обработку HTTP-запросов и возврат ответов. Контроллеры обычно наследуются от класса
ControllerBase или Controller. using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService;
}
[HttpGet("{id}")]
public IActionResult GetUser(int id)
{
var user = _userService.GetUserById(id);
if (user == null)
{
return NotFound();
}
return Ok(user);
}
[HttpPost]
public IActionResult CreateUser([FromBody] User user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_userService.CreateUser(user);
return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
}
}
Сервисы содержат бизнес-логику приложения. Обычно они регистрируются в контейнере зависимостей.
public interface IUserService
{
User GetUserById(int id);
void CreateUser(User user);
}
public class UserService : IUserService
{
private readonly List<User> _users = new List<User>();
public User GetUserById(int id)
{
return _users.FirstOrDefault(u => u.Id == id);
}
public void CreateUser(User user)
{
user.Id = _users.Count + 1;
_users.Add(user);
}
}
Модель данных представляет структуру данных, с которой работает приложение.
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
Регистрация сервисов в
Startup.cs. public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IUserService, UserService>();
}
Настройка маршрутизации для контроллеров в
Startup.cs. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
GET-запрос для получения пользователя
GET /api/users/1
POST-запрос для создания пользователя
POST /api/users
Content-Type: application/json
{
"name": "Alice",
"age": 30
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👀1
Новые запросы к базе данных не могут быть обработаны, так как нет доступных подключений. Это приводит к тому, что запросы отклоняются или истекает время ожидания (timeout).
Запросы могут быть помещены в очередь и ждать доступного подключения, что увеличивает время отклика и снижает производительность системы.
Приложение может выбрасывать исключения, такие как
TimeoutException, SqlException (например, Cannot open connection), указывающие на невозможность установления соединения.try
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// Выполнение операций с базой данных
}
}
catch (SqlException ex)
{
Console.WriteLine("Ошибка подключения к базе данных: " + ex.Message);
}
catch (TimeoutException ex)
{
Console.WriteLine("Превышено время ожидания подключения: " + ex.Message);
}
Неосвобождение ресурсов: Пул подключений может исчерпаться, если подключения не закрываются и не возвращаются в пул после использования. Длительное удержание подключений: Подключения удерживаются слишком долго, например, при выполнении долгих операций в одной сессии.
Чрезмерное количество одновременно выполняемых запросов, превышающее максимальное количество доступных подключений в пуле.
Недостаточное количество максимальных подключений в пуле или слишком большое время ожидания подключения.
Всегда закрывайте соединения после использования, чтобы они возвращались в пул.
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// Выполнение операций с базой данных
connection.Close(); // Явно закрываем подключение
}
Используйте конструкцию
using для автоматического закрытия соединений. using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// Выполнение операций с базой данных
} // Подключение автоматически закрывается здесь
Увеличьте максимальное количество подключений в пуле.
var connectionString = "Data Source=server;Initial Catalog=database;User ID=user;Password=password;Max Pool Size=100;";
Настройте время ожидания подключения.
var connectionString = "Data Source=server;Initial Catalog=database;User ID=user;Password=password;Connection Timeout=30;";
Минимизируйте время удержания соединений. Используйте транзакции эффективно, чтобы не блокировать соединения на долгое время.
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
try
{
// Выполнение операций с базой данных
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥2
В ASP.NET Core можно выполнять действия до и после обработки запроса, не используя middleware, с помощью фильтров действий (Action Filters). Фильтры позволяют выполнять код до и после вызова метода контроллера.
Создадим фильтр, который выполняет код до и после метода действия контроллера.
using Microsoft.AspNetCore.Mvc.Filters;
using System;
public class MyActionFilter : Attribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Код, выполняемый до действия контроллера
Console.WriteLine("До выполнения действия контроллера.");
}
public void OnActionExecuted(ActionExecutedContext context)
{
// Код, выполняемый после действия контроллера
Console.WriteLine("После выполнения действия контроллера.");
}
}
Фильтр можно применить к конкретному методу контроллера или ко всему контроллеру.
using Microsoft.AspNetCore.Mvc;
public class MyController : Controller
{
[MyActionFilter]
public IActionResult MyAction()
{
// Логика действия контроллера
return Ok("Action executed");
}
}
Применение ко всему контроллеру
using Microsoft.AspNetCore.Mvc;
[MyActionFilter]
public class MyController : Controller
{
public IActionResult MyAction1()
{
// Логика действия контроллера
return Ok("Action 1 executed");
}
public IActionResult MyAction2()
{
// Логика действия контроллера
return Ok("Action 2 executed");
}
}
Фильтр также можно зарегистрировать глобально, чтобы он применялся ко всем контроллерам и действиям. Регистрация глобального фильтра в
Startup.cs using Microsoft.AspNetCore.Mvc;
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.Filters.Add<MyActionFilter>();
});
}
Создание фильтра
using Microsoft.AspNetCore.Mvc.Filters;
using System;
public class LoggingActionFilter : Attribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия контроллера
Console.WriteLine("Запрос начался: " + context.HttpContext.Request.Path);
}
public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия контроллера
Console.WriteLine("Запрос завершился: " + context.HttpContext.Request.Path);
}
}
Применение фильтра к контроллеру
using Microsoft.AspNetCore.Mvc;
[LoggingActionFilter]
public class UsersController : Controller
{
public IActionResult GetUser(int id)
{
// Логика действия контроллера
return Ok(new { Id = id, Name = "User" + id });
}
}
Регистрация в
Startup.cs public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Класс сервис-локатора хранит ссылки на сервисы и позволяет запрашивать их по идентификатору, что упрощает управление зависимостями.
Однако этот паттерн критикуют за скрытые зависимости и нарушение принципа инверсии зависимостей (SOLID).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
Это популярный брокер сообщений, который используется для обмена сообщениями между различными компонентами системы. В RabbitMQ есть несколько базовых сущностей, которые нужно понимать для эффективного использования этой технологии.
Это данные, которые отправляются от отправителя к получателю через RabbitMQ. Сообщения могут содержать любые данные: текст, JSON, XML, двоичные данные и т.д.
Это места, где сообщения хранятся до тех пор, пока их не заберет получатель. Очереди обеспечивают надежную доставку сообщений и поддерживают множество получателей.
Создание очереди
rabbitmqadmin declare queue name=my_queue durable=true
Принимают сообщения от отправителей и направляют их в соответствующие очереди на основе правил маршрутизации. Существует несколько типов обменников:
Direct: Сообщения направляются в очередь с ключом маршрутизации, точно соответствующим ключу, указанному в обменнике.
Fanout: Сообщения направляются во все очереди, связанные с этим обменником, без учета ключа маршрутизации.
Topic: Сообщения направляются в очереди на основе шаблонов ключей маршрутизации.
Headers: Сообщения направляются в очереди на основе соответствия заголовков.
Создание обменника:
rabbitmqadmin declare exchange name=my_exchange type=direct durable=true
Определяют правила маршрутизации между обменниками и очередями. Они указывают, какие ключи маршрутизации должны использоваться для доставки сообщений из обменника в очередь.
Создание связи
rabbitmqadmin declare binding source=my_exchange destination=my_queue routing_key=my_key
Ключи маршрутизации используются обменниками для определения, в какие очереди направлять сообщения. Они играют ключевую роль при использовании
direct и topic обменников.Это приложения или службы, которые получают сообщения из очередей и обрабатывают их. Пример производителя на Python
import pika
def callback(ch, method, properties, body):
print(f"Received {body}")
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='my_queue')
channel.basic_consume(queue='my_queue', on_message_callback=callback, auto_ack=True)
print('Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
Это приложения или службы, которые отправляют сообщения в обменники RabbitMQ. Пример производителя на Python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='my_queue')
channel.basic_publish(exchange='', routing_key='my_queue', body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
В языке Python, например, метод get применяется к словарям для безопасного извлечения значения по ключу, возвращая None или значение по умолчанию, если ключ отсутствует.
В JavaScript get может быть геттером, определяющим, как получить значение свойства объекта при его доступе.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4👾1
Типы данных можно классифицировать по нескольким критериям, включая базовые категории, такие как значимые типы (value types) и ссылочные типы (reference types), а также другие характеристики, такие как встроенные типы, пользовательские типы и системы типов.
Значимые типы хранят свои значения непосредственно и обычно располагаются в стеке. При присваивании переменной значимого типа другой переменной создается копия значения.
int a = 10;
int b = a; // b получит копию значения a
Пользовательские типы, которые объединяют несколько значений.
struct Point
{
public int X;
public int Y;
}
Point p1 = new Point { X = 1, Y = 2 };
Point p2 = p1; // p2 получит копию значений p1
Типы, представляющие набор именованных констант.
enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
Days today = Days.Monday;Ссылочные типы хранят ссылки на объекты, которые располагаются в куче (heap). При присваивании переменной ссылочного типа другой переменной копируется ссылка на объект, а не сам объект.
Основные строительные блоки объектов.
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Person p1 = new Person { Name = "Alice", Age = 30 };
Person p2 = p1; // p2 указывает на тот же объект, что и p1
Контракты, определяющие набор методов и свойств, которые должны быть реализованы классами.
interface IAnimal
{
void Speak();
}
class Dog : IAnimal
{
public void Speak() => Console.WriteLine("Woof!");
}
Типы, представляющие ссылки на методы.
delegate void MyDelegate(string message);
MyDelegate del = Console.WriteLine;
del("Hello, World!");
Коллекции элементов одного типа.
int[] numbers = new int[] { 1, 2, 3, 4, 5 }; Последовательности символов.
string greeting = "Hello, World!";
Nullable типы позволяют значимым типам принимать значение
null, что означает отсутствие значения.int? nullableInt = null;
Обобщенные типы позволяют создавать классы, методы и структуры, которые могут работать с любыми типами данных, обеспечивая типобезопасность и повторное использование кода.
class GenericClass<T>
{
public T Value { get; set; }
}
GenericClass<int> intInstance = new GenericClass<int> { Value = 10 };
GenericClass<string> stringInstance = new GenericClass<string> { Value = "Hello" };
Неуправляемые типы позволяют работать с указателями и выполнять низкоуровневые операции, которые обычно не разрешены в безопасном управляемом коде.
unsafe
{
int x = 10;
int* ptr = &x;
Console.WriteLine((int)ptr); // Вывод адреса переменной x
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚Базу Знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Значимые типы обычно хранятся на стеке, когда они объявлены внутри метода. Это происходит потому, что стек обеспечивает быстрый доступ и автоматическое управление памятью.
void MyMethod()
{
int localVar = 10; // localVar хранится на стеке
}
Значимые типы могут храниться в куче, если они являются частью объекта ссылочного типа. Например, если структура или переменная типа
int является полем класса, то она будет храниться в куче вместе с объектом класса.class MyClass
{
public int Number; // Number хранится в куче, потому что MyClass - ссылочный тип
}
MyClass obj = new MyClass();
obj.Number = 42;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Существует два способа избежать упаковки и распаковки (boxing и unboxing) значимых типов при их хранении в коллекциях или использовании в других ситуациях, где тип данных не должен быть упакован в объект.
Обобщения позволяют создавать коллекции и методы, которые работают с любыми типами данных без необходимости упаковки.
// Пример использования обобщённого списка для значимого типа int
List<int> numbers = new List<int>();
numbers.Add(10); // Добавление без упаковки
int number = numbers[0]; // Чтение без распаковки
В некоторых случаях для избежания упаковки можно создать специальные структуры, которые содержат необходимые данные и методы.
// Обобщённый метод для работы с любыми типами данных без упаковки
public T FindMax<T>(T a, T b) where T : IComparable<T>
{
return a.CompareTo(b) > 0 ? a : b;
}
// Использование метода для значимого типа int
int max = FindMax(3, 5);
Console.WriteLine(max); // Выведет: 5
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1🤔1
Чем отличается метод Equal от ==? Equals проверяет логическое равенство объектов, а == сравнивает ссылки для объектов и значения для примитивов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1
string является ссылочным типом, хотя по поведению он похож на значимый тип. Это означает, что переменная типа string содержит ссылку на объект строки, хранящийся в памяти, а не непосредственно данные.Объекты типа
string неизменяемы. Это означает, что после создания строки её содержимое нельзя изменить. Любые операции, которые кажутся изменяющими строку (например, Replace, Substring), на самом деле создают новую строку. string original = "Hello";
string modified = original.Replace('H', 'J'); // Создаётся новая строка "Jello"
string поддерживает различные операторы и методы для работы с текстом. Например, оператор + для конкатенации строк, метод Substring для извлечения подстрок, метод Split для разбиения строки и т.д. string hello = "Hello";
string world = "World";
string concatenated = hello + " " + world; // "Hello World"
Для оптимизации памяти строки могут интернироваться. Это означает, что строки с одинаковым содержимым могут храниться в единственном экземпляре в пуле строк.
string a = "test";
string b = "test";
bool areEqual = object.ReferenceEquals(a, b); // True, потому что строки интернированы
string имеет специальную поддержку на уровне языка. Например, строковые литералы в коде автоматически рассматриваются как объекты типа string. string greeting = "Hello, world!";
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8