Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core 7
Рассмотрим, как в 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. Например, выберем из бд всех пользователей, которые работают в компании "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})"); }
Начиная с версии 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(). Данный метод не является методом 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
Но в качестве альтернативы мы можем использовать методы 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, которые извлекают соответственно любой единственный элемент и последний элемент последовательности.