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.

Entity Framework Core
Entity Framework Core
A lightweight, extensible, open-source, and cross-platform version of the Entity Framework data access technology.
695 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Daniel Zhang-MSFT 9,611 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,031 Reputation points
    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.