1

Does the FirstOrDefaultAsync method provided by Microsoft.EntityFrameworkCore trigger Entity Framework (EF) to start tracking a given entity?

For example, as far as I understand, the AddAsync method "tells" EF to start tracking a given entity.

Thanks!

Kyle
  • 59
  • 6
  • Yes. All functions which returns single or collection of FULL items (not custom projected via `Select`) are tracked by EF Core automatically. – Svyatoslav Danyliv Jul 04 '23 at 08:49
  • @topsail I started a new job and am trying to understand an existing codebase. I'll provide what I can below. – Kyle Jul 04 '23 at 22:41
  • "Yes. All functions which returns single or collection of FULL items (not custom projected via Select) are tracked by EF Core automatically. – Svyatoslav Danyliv" Thanks for your input. @wenbingeng-MSFT seems to think differently (see their answer below). – Kyle Jul 04 '23 at 22:46

1 Answers1

0

The FirstOrDefaultAsync method is used to retrieve the first element that satisfies the specified criteria, or the default value if no such element is found. It is a query method that does not involve modifying the state of the entity or instructing EF to track the entity.

AddAsync() is 100% async safe, while Add() is only async safe in certain conditions. For details, you can refer to AddAsync() vs Add() in EF Core

None of these are directly related to tracking a given entity.

For tracking a given entity, you can pay more attention to SaveChanges, the following is an example, by catching DbUpdateException to track entities and fields, because DbUpdateException is usually an error reported in SaveChanges:

         try
         {

             using (var context = new EfContext())
             {

                 var data = new TestTable
                 {
                     Status = TestTableStatus.Status1.ToString(),
                     Content = "One-to-many test",
                     TestTableItems = new List<TestTableItem> {
                     new TestTableItem { Name = "Add one-to-many 1", Id = 123},

                     new TestTableItem {Name = "Add one-to-many 2" } }
                 };

                 context. Add(data);

                 await context. SaveChangesAsync();
             }
         }
         catch (DbUpdateException ex)
         {

             var failedEntries = ex.Entries;
             foreach (var entry in failedEntries)
             {
                 var entityName = entry. Metadata. Name;
                 Console.WriteLine($"Failed to add in entity: {entityName}");

             }
         }

enter image description here

wenbingeng-MSFT
  • 1,546
  • 1
  • 1
  • 8
  • Thanks for your input! One of the other folks who replied seems to disagree with you (I say that respectfully). @Svyatoslav Danyliv said, "Yes. All functions which returns single or collection of FULL items (not custom projected via Select) are tracked by EF Core automatically." I need a tie breaker answer I suppose. Funny enough, Chat GPT was giving me mixed signals as well which is why I came here! :o) – Kyle Jul 04 '23 at 22:51
  • @Kyle Hi, it seems you have misunderstood me a bit. I agree with Svyatoslav Danyliv. But it doesn't seem to be the code you pointed out that actually does the tracking for a given entity. Instead, SaveChanges. I hope my answer can help you – wenbingeng-MSFT Jul 05 '23 at 02:12
  • @wenbengeng-MSFT Thank you for your time! Here's some example code that is illustrative of my actual code. Assume `context` is an instance of a `DbContext`, `Characteristic` is a property of `context` and also an instance of `DbSet`, and `id` is a parameter passed by the calling method. Furthermore, assume `Characteristic` has an int `Id` property and a boolean `IsActive` property. `var entity = context.Characteristic.FirstOrDefaultAsync(c => c.Id.Equals(id)); entity.IsActive = false; context.SaveChangesAsync();` Which of those prior lines of code "tells" EF to start tracking? – Kyle Jul 05 '23 at 15:18
  • @Kyle Hi, start tracking from "var entity = context.Characteristic.FirstOrDefaultAsync(c => c.Id.Equals(id));", here it is context that plays a role in tracking. But it is easier to catch the tracked entity by DbUpdateException at "context.SaveChangesAsync();", as shown in the above code. – wenbingeng-MSFT Jul 06 '23 at 01:38
  • Thank you! So just to clarify, you're saying the line `context.Characteristic.FirstOrDefaultAsync(c => c.Id.Equals(id))` is where EF starts to track the entity? – Kyle Jul 06 '23 at 15:12
  • @Kyle Yes, if my answer is helpful to you, you can mark it so that it can help more people – wenbingeng-MSFT Jul 07 '23 at 01:20