« Entity Framework Plus » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
Aucun résumé des modifications |
|||
(7 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 3 : | Ligne 3 : | ||
* [https://entityframework-plus.net Entity Framework Plus] | * [https://entityframework-plus.net Entity Framework Plus] | ||
* [https://github.com/zzzprojects/EntityFramework-Plus Git repository] | * [https://github.com/zzzprojects/EntityFramework-Plus Git repository] | ||
* [https://entityframework-plus.net/download Price and free features] | |||
= Nuget package = | = Nuget package = | ||
Ligne 10 : | Ligne 11 : | ||
= [https://entityframework-plus.net/ef-core-query-cache Query cache] = | = [https://entityframework-plus.net/ef-core-query-cache Query cache] = | ||
{{warn | With cache, entities are fetched without tracking.}} | |||
<kode lang='cs'> | <kode lang='cs'> | ||
var items = await context.Items.FromCacheAsync(); | var items = await context.Items.FromCacheAsync(cancellationToken, "Cache Tag", "Repository Name", GetType().Name); | ||
// The first call perform a database round trip | // The first call perform a database round trip | ||
// The following calls will take the value from the memory instead | // The following calls will take the value from the memory instead | ||
Ligne 17 : | Ligne 19 : | ||
// for immediate methods (count, first, single, contains, any), use a query Deferred | // for immediate methods (count, first, single, contains, any), use a query Deferred | ||
var count = await context.Items.DeferredCount().FromCacheAsync(); | var count = await context.Items.DeferredCount().FromCacheAsync(); | ||
// expire all caches tagged with "Cache Tag" | |||
QueryCacheManager.ExpireTag("Cache Tag"); | |||
</kode> | </kode> | ||
Ligne 31 : | Ligne 36 : | ||
var futureItemCount = await context.Items.DeferredCount().FutureValue(); | var futureItemCount = await context.Items.DeferredCount().FutureValue(); | ||
var count = futureItemCount.Value; | var count = futureItemCount.Value; | ||
</kode> | |||
= [https://entityframework-plus.net/ef-core-query-include-filter Query IncludeFilter] = | |||
Allow to filter the included related entities. Useful only for many to many relationships.<br> | |||
It improves the performance because fewer elements are joined. | |||
<kode lang='cs'> | |||
// get items belonging to the category C2. | |||
context.Items.IncludeFilter(x => x.Categories.Where(x => x.Name == "C2")); | |||
</kode> | |||
<kode lang='mariadb'> | |||
SELECT `t`.`id`, `t`.`name` | |||
FROM `item` AS `i` | |||
INNER JOIN ( | |||
SELECT `c`.`id`, `c`.`name`, `i0`.`itemId` | |||
FROM `itemCategory` AS `i0` | |||
INNER JOIN `category` AS `c` ON `i0`.`categoryId` = `c`.`id` | |||
WHERE `c`.`name` = 'C2' | |||
) AS `t` ON `i`.`id` = `t`.`itemId` | |||
</kode> | </kode> | ||
Dernière version du 16 juin 2024 à 18:05
Links
Nuget package
dotnet add package Z.EntityFramework.Plus.EFCore |
Query cache
With cache, entities are fetched without tracking. |
var items = await context.Items.FromCacheAsync(cancellationToken, "Cache Tag", "Repository Name", GetType().Name); // The first call perform a database round trip // The following calls will take the value from the memory instead // for immediate methods (count, first, single, contains, any), use a query Deferred var count = await context.Items.DeferredCount().FromCacheAsync(); // expire all caches tagged with "Cache Tag" QueryCacheManager.ExpireTag("Cache Tag"); |
Query Future
Allow to reduce database roundtrip by batching multiple queries in the same sql command.
var futureItems = dbContext.Items.Future(); var futureCategories = dbContext.Categories.Future(); // TRIGGER all pending queries (futureItems & futureCategories) var items = await futureItems.ToListAsync(); // for immediate methods (count, first, single, contains, any), use a query Deferred var futureItemCount = await context.Items.DeferredCount().FutureValue(); var count = futureItemCount.Value; |
Query IncludeFilter
Allow to filter the included related entities. Useful only for many to many relationships.
It improves the performance because fewer elements are joined.
// get items belonging to the category C2. context.Items.IncludeFilter(x => x.Categories.Where(x => x.Name == "C2")); |
SELECT `t`.`id`, `t`.`name` FROM `item` AS `i` INNER JOIN ( SELECT `c`.`id`, `c`.`name`, `i0`.`itemId` FROM `itemCategory` AS `i0` INNER JOIN `category` AS `c` ON `i0`.`categoryId` = `c`.`id` WHERE `c`.`name` = 'C2' ) AS `t` ON `i`.`id` = `t`.`itemId` |
Audit
Allow to easily track changes, exclude/include entity or property and auto save audit entries in the database.
Batch update
EF Core 7 ExecuteUpdate can handle this scenario |
context.Items.Where(x => ids.Contains(x.Id)) .UpdateAsync(x => new Item { Name = "new name" }, x => { x.Executing = command => Console.WriteLine(command.CommandText); }); |
UPDATE A SET A.[Name] = @zzz_BatchUpdate_0 FROM [Items] AS A INNER JOIN ( SELECT [i].[Id], [i].[Name] FROM [Items] AS [i] WHERE [i].[Id] IN (1, 2) ) AS B ON A.[Id] = B.[Id] |
- Updates multiples rows
- in a single database roundtrip
- without loading entities in the context
Limitations:
- Do not support Complex Type
- Do not support TPC
- Do not support TPH
- Do not support TPT
If you need to use one of this feature, you need to use the paying library Entity Framework Extensions
Batch delete
EF Core 7 ExecuteDelete can handle this scenario |
- Deletes multiples rows
- in a single database roundtrip
- without loading entities in the context