Entity framework поиск по таблице
Рассмотрим, как в EF Core выполнять фильтрацию. Для этого используем модели из прошлой темы:
Find(Type, Object[])
Обнаруживает сущность с указанными значениями первичного ключа. Если сущность с заданными значениями первичного ключа отслеживается в контексте, то она возвращается немедленно, без выполнения запроса к базе данных. В противном случае выполняется запрос к базе данных для сущности с заданными значениями первичного ключа, и эта сущность, если она найдена, присоединяется к контексту и возвращается. Если сущность не найдена, возвращается значение null.
Рассмотрим, как в EF Core выполнять фильтрацию. Для этого используем модели из прошлой темы:
Перегрузки
Обнаруживает сущность с указанными значениями первичного ключа. Если сущность с заданными значениями первичного ключа отслеживается в контексте, то она возвращается немедленно, без выполнения запроса к базе данных. В противном случае выполняется запрос к базе данных для сущности с заданными значениями первичного ключа, и эта сущность, если она найдена, присоединяется к контексту и возвращается. Если сущность не найдена, возвращается значение null.
Обнаруживает сущность с указанными значениями первичного ключа. Если сущность с заданными значениями первичного ключа отслеживается в контексте, то она возвращается немедленно, без выполнения запроса к базе данных. В противном случае выполняется запрос к базе данных для сущности с заданными значениями первичного ключа, и эта сущность, если она найдена, присоединяется к контексту и возвращается. Если сущность не найдена, возвращается значение null.
EF.Functions.Like
Начиная с версии 2.0 в Entity Framework Core можно использовать метод EF.Functions.Like() . Он позволяет транслировать условие в выражение с оператором LIKE на стороне MS SQL Server. Метод принимает два параметра - оцениваемое выражение и шаблон, с которым сравнивается его значение. Например, найдем всех пользователей, в имени которых присутствует подстрока "Tom" (это могут быть "Tom", "Tomas", "Tomek", "Smith Tom"):
На стороне БД этот запрос будет транслироваться в следующую SQL-команду:
Для определения шаблона могут применяться ряд специальных символов подстановки:
% : соответствует любой подстроке, которая может иметь любое количество символов, при этом подстрока может и не содержать ни одного символа
_ : соответствует любому одиночному символу
[ ] : соответствует одному символу, который указан в квадратных скобках
[ - ] : соответствует одному символу из определенного диапазона
[ ^ ] : соответствует одному символу, который не указан после символа ^
Стоит отметить, что в качестве первого параметра метод принимает оцениваемое выражение в виде строки. В случае со свойством Name все просто, так как оно представляет тип string. Но если нам необходимо использовать в качестве оцеениваемого выражения другие свойства, то их следует привести к строке. Например, найдем всех пользователей у которых возраст (свойство Age) в диапазоне от 22 до 29:
Например, следующее выражение:
Подобным образом метод EF.Functions.Like() можно использовать с операторами LINQ:
Для выборки одного объекта мы можем использовать метод Find() . Данный метод не является методом Linq, он определен у класса DbSet:
При выполнении запроса он будет трансформироваться в следующее выражение SQL:
Finding an entity by composite primary key
Entity Framework allows your entities to have composite keys - that's a key that is made up of more than one property. For example, you could have a BlogSettings entity that represents a users settings for a particular blog. Because a user would only ever have one BlogSettings for each blog you could chose to make the primary key of BlogSettings a combination of BlogId and Username. The following code attempts to find the BlogSettings with BlogId = 3 and Username = "johndoe1987":
Note that when you have composite keys you need to use ColumnAttribute or the fluent API to specify an ordering for the properties of the composite key. The call to Find must use this order when specifying the values that form the key.
В этом разделе рассматриваются различные способы запроса данных с помощью Entity Framework, включая LINQ и метод Find. Методы, представленные в этом разделе, также применимы к моделям, созданным с помощью Code First и конструктора EF.
First/FirstOrDefault/FirstAsync/FirstOrDefaultAsync
Но в качестве альтернативы мы можем использовать методы Linq First()/FirstOrDefault() и их асинхронные версии FirstAsync()/FirstOrDefaultAsync() . Они получают первый элемент выборки, который соответствует определенному условию или набору условий. Использование метода FirstOrDefault() является более гибким, так как если выборка пуста, то он вернет значение null. А метод First() в той же ситуации выбросит ошибку.
С помощью данных методов можно просто получить первый объект из выборки:
Но в качестве параметра также можно передать условие. Тогда в выборку попадают только те объекты, которые соответствуют условию:
По тому же принципу работают пары методов Single/SingleOrDefault и Last/LastOrDefault , которые извлекают соответственно любой единственный элемент и последний элемент последовательности.
This topic covers the various ways you can query for data using Entity Framework, including LINQ and the Find method. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.
Where
Если необходимо отфильтровать получаемые данные, то для этого можно использовать метод Where . Например, выберем из бд всех пользователей, которые работают в компании "Google":
Аналогичный запос с помощью операторов LINQ:
Finding an entity by primary key
The following code shows some uses of Find:
Finding entities using a query
DbSet and IDbSet implement IQueryable and so can be used as the starting point for writing a LINQ query against the database. This is not the appropriate place for an in-depth discussion of LINQ, but here are a couple of simple examples:
Note that DbSet and IDbSet always create queries against the database and will always involve a round trip to the database even if the entities returned already exist in the context. A query is executed against the database when:
When results are returned from the database, objects that do not exist in the context are attached to the context. If an object is already in the context, the existing object is returned (the current and original values of the object's properties in the entry are not overwritten with database values).
When you perform a query, entities that have been added to the context but have not yet been saved to the database are not returned as part of the result set. To get the data that is in the context, see Local Data.
If a query returns no rows from the database, the result will be an empty collection, rather than null.
First/FirstOrDefault
Но в качестве альтернативы мы можем использовать методы Linq First()/FirstOrDefault() . Они получают первый элемент выборки, который соответствует определенному условию или набору условий. Использование метода FirstOrDefault() является более гибким, так как если выборка пуста, то он вернет значение null. А метод First() в той же ситуации выбросит ошибку.
По тому же принципу работают пары методов Single/SingleOrDefault и Last/LastOrDefault , которые извлекают соответственно любой единственный элемент и последний элемент последовательности.
EF.Functions.Like
С помощью метода EF.Functions.Like() можно задать условие запроса, которое транслируется в Entity Framework Core в выражение с оператором LIKE. Метод принимает два параметра - оцениваемое выражение и шаблон, с которым сравнивается его значение. Например, найдем всех пользователей, в имени которых присутствует подстрока "Tom" (это могут быть "Tom", "Tomas", "Tomek", "Smith Tom"):
Выражение EF.Functions.Like(p.Name!, "%Tom%")) означает, что мы ищем строки, где в свойстве Name содержиться подстрока "Tom". Поскольку Name представляет nullable-тип, то после названия свойства указывается оператор !.
На стороне БД этот запрос будет транслироваться в следующую SQL-команду:
Для определения шаблона могут применяться ряд специальных символов подстановки:
% : соответствует любой подстроке, которая может иметь любое количество символов, при этом подстрока может и не содержать ни одного символа
_ : соответствует любому одиночному символу
[ ] : соответствует одному символу, который указан в квадратных скобках
[ - ] : соответствует одному символу из определенного диапазона
[ ^ ] : соответствует одному символу, который не указан после символа ^
Стоит отметить, что в качестве первого параметра метод принимает оцениваемое выражение в виде строки. В случае со свойством Name все просто, так как оно представляет тип string. Но если нам необходимо использовать в качестве оцеениваемого выражения другие свойства, то их следует привести к строке. Например, найдем всех пользователей у которых возраст (свойство Age) в диапазоне от 20 до 29:
Например, следующее выражение:
Подобным образом метод EF.Functions.Like() можно использовать с операторами LINQ:
Поиск сущности по первичному ключу
В коде ниже приведено несколько примеров использования метода Find.
Where
Если необходимо отфильтровать получаемые данные, то для этого можно использовать метод Where . Например, выберем из бд всех пользователей, которые работают в компании "Google":
Аналогичный запос с помощью операторов LINQ:
Поиск сущностей с помощью первичных ключей
Метод Find в классе DbSet использует значение первичного ключа, чтобы найти сущность, отслеживаемую контекстом. Если сущность не найдена в контексте, запрос отправляется в базу данных для поиска сущности там. Если сущность не найдена в контексте или в базе данных, возвращается значение NULL.
Метод Find имеет два важных отличия от запроса:
- Круговой путь к базе данных будет использоваться только в том случае, если сущность с указанным ключом не найдена в контексте.
- Метод Find возвращает сущности в состоянии "Добавлено". Это значит, что метод Find возвращает сущности, которые были добавлены в контекст, но еще не были сохранены в базе данных.
Find/FindAsync
Для выборки одного объекта мы можем использовать метод Find()/FindAsync() . Данный метод не является методом Linq, он определен у класса DbSet:
При выполнении запроса он будет трансформироваться в следующее выражение SQL:
Finding entities using primary keys
The Find method on DbSet uses the primary key value to attempt to find an entity tracked by the context. If the entity is not found in the context then a query will be sent to the database to find the entity there. Null is returned if the entity is not found in the context or in the database.
Find is different from using a query in two significant ways:
- A round-trip to the database will only be made if the entity with the given key is not found in the context.
- Find will return entities that are in the Added state. That is, Find will return entities that have been added to the context but have not yet been saved to the database.
Поиск сущностей с помощью запроса
DbSet и IDbSet реализуют IQueryable, поэтому их можно использовать как начальную точку для написания запроса LINQ к базе данных. Здесь мы не будем подробно рассматривать LINQ, но приведем несколько простых примеров:
Обратите внимание, что DbSet и IDbSet всегда создают запросы к базе данных и всегда используют круговой путь к базе данных, даже если возвращаемые сущности уже присутствуют в контексте. Запрос выполняется в базе данных, если:
Когда из базы данных возвращаются результаты, объекты, отсутствующие в контексте, присоединяются к контексту. Если объект уже есть в контексте, возвращается существующий объект (текущие и исходные значения свойств объекта в записи не переписываются значениями из базы данных).
Когда вы выполняете запрос, сущности, которые были добавлены в контекст, но еще не были сохранены в базе данных, не возвращаются в составе результирующего набора. Чтобы получить данные из контекста, см. раздел Локальные данные.
Если запрос не возвращает строки из базы данных, результатом будет пустая коллекция, а не NULL.
Where
Если необходимо отфильтровать получаемые данные, то для этого можно использовать метод Where . Например, выберем из бд всех пользователей, которые работают в компании "Google":
Аналогичный запос с помощью операторов LINQ:
Поиск сущности по составному первичному ключу
Платформа Entity Framework позволяет сущностям иметь составные ключи, то есть ключи, состоящие из нескольких свойств. Например, вы можете создать сущность BlogSettings, которая представляет собой параметры пользователей для конкретного блога. Так как пользователю необходима только одна сущность BlogSettings для каждого блога, первичный ключ для BlogSettings может состоять из комбинации идентификатора блога и имени пользователя. Следующий код пытается найти BlogSettings по идентификатору = 3 и имени пользователя = johndoe1987:
Если у вас есть составные ключи, вам нужно использовать ColumnAttribute или текучий API, чтобы указать порядок свойств составного ключа. В вызове метода Find эти значения ключа должны указываться в том же порядке.
Пространство имен: Microsoft.EntityFrameworkCore Сборка: Microsoft.EntityFrameworkCore.dll Пакет: Microsoft.EntityFrameworkCore v1.1.6 Пакет: Microsoft.EntityFrameworkCore v2.0.3 Пакет: Microsoft.EntityFrameworkCore v2.1.11 Пакет: Microsoft.EntityFrameworkCore v2.2.6 Пакет: Microsoft.EntityFrameworkCore v3.0.0 Пакет: Microsoft.EntityFrameworkCore v3.1.0 Пакет: Microsoft.EntityFrameworkCore v5.0.0 Пакет: Microsoft.EntityFrameworkCore v6.0.0
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Читайте также: