question

JJTT-0327 avatar image
0 Votes"
JJTT-0327 asked ·

EF Core Generic Repository get Id from new inserted generic entity async

Goal: get id of the inserted generic entity by using async with ASP.NET Core 3

Problem: what part am I missing in order to achieve the goal?

Code:

     public async Task<int> AddAsync(T entity)
     {
         if (entity == null)
         {
             throw new ArgumentNullException($"{nameof(AddAsync)} entity must not be null");
         }
        
         try
         {
             await _context.AddAsync(entity);
             await _context.SaveChangesAsync();
        
             return <Id Here>   
         }
         catch (Exception)
         {
             throw new Exception($"{nameof(entity)} could not be saved");
         }
     }


Thank you!



61468-a.png

It doesn't work to use id.




dotnet-entity-framework-core
a.png (30.5 KiB)
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

DanielZhang-MSFT avatar image
0 Votes"
DanielZhang-MSFT answered ·

Hi JJTT-0327,
First, you can try to use reflection to obtain the Id property.

 var IdProperty = entity.GetType().GetProperty("Id").GetValue(entity,null);
 return (int)IdProperty;

In general, the table in database has auto-generated integer identity Id as primary key.
If your Id is primary key, kuncevic.dev has provided a better solution in this thread you can refer to.
Best Regards,
Daniel Zhang


If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered ·

You could use an Interface e.g. quick-n-dirty. Customer and Manager will work with AddAsync as per the constraint while SalesRepresentative will not as it fails to meet the where constraint.

 public interface TEntity
 {
     int Identifier { get;} 
 }
    
 public class Customer : TEntity
 {
     public int Id { get; set; }
     public int Identifier => Id;
 }
 public class Manager : TEntity
 {
     public int Id { get; set; }
     public int Identifier => Id;
 }
 public class SalesRepresentative 
 {
     public int Id { get; set; }
     public int Identifier => Id;
 }
    
 public class GenericRepository<T> where T : TEntity
 {
     public async Task<int> AddAsync(T entity)
     {
         return ((TEntity) entity).Identifier;
     }
 }




·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

WadeGausdenNZ avatar image
0 Votes"
WadeGausdenNZ answered ·

While Karen's answer is correct, I do want to point out that Entity Framework will automatically hydrate your models with identity fields when you insert. So for example if I have :

 class Customer 
 {
    public int Id { get; set; }
    public string Name { get; set; }
 }
    
 class CustomerService 
 {
     int MyMethod()
     {
         var customer = new Customer { Name = "Abc" };
            
         _customerRepository.Add(customer);
            
         return customer.Id; //Notice how we never touched this field, but after our insert, EF will populate it for us. 
     }
 }

Notice how we don't add or modify the Id field, but after our insert, we can return it fine. While this may not work perfectly in your scenario, I just wanted to show that your add method may not need to return the identity at all, as if you have a reference to the original object, the ID will be set within it.

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.