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

JJ TT 141 Reputation points
2021-01-28T18:04:08.617+00:00

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.

Developer technologies | .NET | Entity Framework Core
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Daniel Zhang-MSFT 9,656 Reputation points
    2021-01-29T03:05:57.893+00:00

    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.

    1 person found this answer helpful.
    0 comments No comments

  2. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2021-02-01T16:47:46.047+00:00

    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;
        }
    }
    
    0 comments No comments

  3. Wade Gausden 166 Reputation points
    2021-03-07T00:55:53.16+00:00

    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.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.