« 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

Bash.svg
dotnet add package Z.EntityFramework.Plus.EFCore

Query cache

With cache, entities are fetched without tracking.
Cs.svg
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.

Cs.svg
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.

Cs.svg
// get items belonging to the category C2.
context.Items.IncludeFilter(x => x.Categories.Where(x => x.Name == "C2"));
Mariadb.svg
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
Csharp.svg
context.Items.Where(x => ids.Contains(x.Id))
             .UpdateAsync(x => new Item { Name = "new name" },
                          x =>
                          {
                              x.Executing = command => Console.WriteLine(command.CommandText);
                          });
Tsql.svg
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