Выборка и фильтрация
Рассмотрим, как в EF Core выполнять фильтрацию. Для этого используем модели из прошлой темы:
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public List<User> Users { get; set; } = new List<User>();
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public int CompanyId { get; set; }
public Company Company { get; set; }
}
public class ApplicationContext : DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=helloappdb;Trusted_Connection=True;");
}
}
Where
Если необходимо отфильтровать получаемые данные, то для этого можно использовать метод Where. Например, выберем из бд всех пользователей, которые работают в компании "Google":
using(ApplicationContext db = new ApplicationContext())
{
var users = db.Users.Where(p=> p.Company.Name=="Google");
foreach (User user in users)
Console.WriteLine($"{user.Name} ({user.Age})");
}
Аналогичный запрос с помощью операторов LINQ:
using(ApplicationContext db = new ApplicationContext())
{
var users = (from user in db.Users
where user.Company.Name == "Google"
select user).ToList();
foreach (User user in users)
Console.WriteLine($"{user.Name} ({user.Age})");
}
EF.Functions.Like
Начиная с версии 2.0 в Entity Framework Core можно использовать метод EF.Functions.Like(). Он позволяет транслировать условие в выражение с оператором LIKE на стороне MS SQL Server. Метод принимает два параметра - оцениваемое выражение и шаблон, с которым сравнивается его значение. Например, найдем всех пользователей, в имени которых присутствует подстрока "Tom" (это могут быть "Tom", "Tomas", "Tomek", "Smith Tom"):
using (ApplicationContext db = new ApplicationContext())
{
var users = db.Users.Where(p => EF.Functions.Like(p.Name, "%Tom%"));
foreach (User user in users)
Console.WriteLine($"{user.Name} ({user.Age})");
}
На стороне БД этот запрос будет транслироваться в следующую SQL-команду:
SELECT [p].[Id], [p].[CompanyId], [p].[Name], [p].[Age]
FROM [Users] AS [p]
WHERE [p].[Name] LIKE N'%Tom%'
Для определения шаблона могут применяться ряд специальных символов подстановки:
%: соответствует любой подстроке, которая может иметь любое количество символов, при этом подстрока может и не содержать ни одного символа
_: соответствует любому одиночному символу
[ ]: соответствует одному символу, который указан в квадратных скобках
[ - ]: соответствует одному символу из определенного диапазона
[ ^ ]: соответствует одному символу, который не указан после символа ^
Стоит отметить, что в качестве первого параметра метод принимает оцениваемое выражение в виде строки. В случае со свойством Name все просто, так как оно представляет тип string. Но если нам необходимо использовать в качестве оцеениваемого выражения другие свойства, то их следует привести к строке. Например, найдем всех пользователей у которых возраст (свойство Age) в диапазоне от 22 до 29:
Например, следующее выражение:
var users = db.Users.Where(u => EF.Functions.Like(u.Age.ToString(), "2[2-9]"));
Подобным образом метод EF.Functions.Like() можно использовать с операторами LINQ:
var users = from u in db.Users
where EF.Functions.Like(u.Age.ToString(), "2[2-9]")
select u;
Find
Для выборки одного объекта мы можем использовать метод Find(). Данный метод не является методом Linq, он определен у класса DbSet:
User user = db.Users.Find(3); // выберем элемент с id=3
При выполнении запроса он будет трансформироваться в следующее выражение SQL:
SELECT TOP(1) [e].[Id], [e].[CompanyId], [e].[Name], [e].[Age]
FROM [Users] AS [e]
WHERE [e].[Id] = 3
First/FirstOrDefault
Но в качестве альтернативы мы можем использовать методы Linq First()/FirstOrDefault(). Они получают первый элемент выборки, который соответствует определенному условию или набору условий. Использование метода FirstOrDefault()
является более гибким, так как если выборка пуста, то он вернет значение null. А метод First()
в той же ситуации выбросит ошибку.
User user = db.Users.FirstOrDefault(p=>p.Id==3);
if(user!=null)
Console.WriteLine(user.Name);
По тому же принципу работают пары методов Single/SingleOrDefault и Last/LastOrDefault, которые извлекают соответственно любой единственный элемент и последний элемент последовательности.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.