DBSet.Find() API missing in Entity Framework Core Final RC1 Version

Recently, I was writing the infrastructure part of My Movie Review SPA app using ASP.NET Core version. Then, I landed in a really weird situation where in DBSet.Find() a piece is missing. This is a really crucial extension method for finding the record based on the primary key. In order to find the solution, I thought it would be nice to talk to EF Guru Julie Lerman directly. Here is what I asked her and what she replied on the same.
 

Here, at this point I got the confirmation, this feature is yet to be included by EF Team. Hence, I decided to use the interim solution provided by the EF Team themselves. Below is the extension method which I have written to serve the same result.
  1. using System;  
  2. using System.Linq;  
  3. using System.Linq.Expressions;  
  4. using Microsoft.Data.Entity;  
  5. using Microsoft.Data.Entity.Infrastructure;  
  6.   
  7. namespace MovieReviewSPA.Data.Helpers  
  8. {  
  9.     public static class Extensions  
  10.     {  
  11.         public static TEntity Find<TEntity>(this DbSet<TEntity> setparams object[] keyValues) where TEntity : class  
  12.         {  
  13.             var context = ((IInfrastructure<IServiceProvider>)set).GetService<DbContext>();  
  14.   
  15.             var entityType = context.Model.FindEntityType(typeof(TEntity));  
  16.             var key = entityType.FindPrimaryKey();  
  17.   
  18.             var entries = context.ChangeTracker.Entries<TEntity>();  
  19.   
  20.             var i = 0;  
  21.             foreach (var property in key.Properties)  
  22.             {  
  23.                 entries = Enumerable.Where(entries, e => e.Property(property.Name).CurrentValue == keyValues[i]);  
  24.                 i++;  
  25.             }  
  26.   
  27.             var entry = entries.FirstOrDefault();  
  28.             if (entry != null)  
  29.             {  
  30.                 // Return the local object if it exists.  
  31.                 return entry.Entity;  
  32.             }  
  33.   
  34.             // TODO: Build the real LINQ Expression  
  35.             // set.Where(x => x.Id == keyValues[0]);  
  36.             var parameter = Expression.Parameter(typeof(TEntity), "x");  
  37.             var query = Queryable.Where(set, (Expression<Func<TEntity, bool>>)  
  38.                 Expression.Lambda(  
  39.                     Expression.Equal(  
  40.                         Expression.Property(parameter, "Id"),  
  41.                         Expression.Constant(keyValues[0])),  
  42.                     parameter));  
  43.   
  44.             // Look in the database  
  45.             return query.FirstOrDefault();  
  46.         }  
  47.     }  

And, here is the completed Repository Pattern for my project.
  1. using System;  
  2. using System.Linq;  
  3. using Microsoft.Data.Entity;  
  4. using Microsoft.Data.Entity.ChangeTracking;  
  5. using MovieReviewSPA.Data.Contracts;  
  6. using MovieReviewSPA.Data.Helpers;  
  7. using DbContext = Microsoft.Data.Entity.DbContext;  
  8. using EntityState = Microsoft.Data.Entity.EntityState;  
  9.   
  10. namespace MovieReviewSPA.Data  
  11. {  
  12.     public class EFRepository<T> : IRepository<T> where T : class  
  13.     {  
  14.         public EFRepository(DbContext dbContext)  
  15.         {  
  16.             if (dbContext == null)  
  17.                 throw new ArgumentNullException("dbContext");  
  18.             DbContext = dbContext;  
  19.             DbSet = DbContext.Set<T>();  
  20.         }  
  21.   
  22.         protected DbContext DbContext { getset; }  
  23.         protected DbSet<T> DbSet { getset; }  
  24.         public virtual IQueryable<T> GetAll()  
  25.         {  
  26.             return DbSet;  
  27.         }  
  28.   
  29.         public virtual T GetById(int id)  
  30.         {  
  31.             //EF Core Will be updated shortly with Find Extension by Default  
  32.             //Here, I have written Extension method for the same  
  33.             //Source:- http://stackoverflow.com/questions/29030472/dbset-doesnt-have-a-find-method-in-ef7/29082410#29082410  
  34.             return DbSet.Find(id);  
  35.         }  
  36.   
  37.         public virtual void Add(T entity)  
  38.         {  
  39.             EntityEntry<T> dbEntityEntry = DbContext.Entry(entity);  
  40.             if (dbEntityEntry.State != (EntityState) EntityState.Detached)  
  41.             {  
  42.                 dbEntityEntry.State = EntityState.Added;  
  43.             }  
  44.             else  
  45.             {  
  46.                 DbSet.Add(entity);  
  47.             }  
  48.         }  
  49.   
  50.         public virtual void Update(T entity)  
  51.         {  
  52.             EntityEntry<T> dbEntityEntry = DbContext.Entry(entity);  
  53.             if (dbEntityEntry.State != (EntityState) EntityState.Detached)  
  54.             {  
  55.                 DbSet.Attach(entity);  
  56.             }  
  57.             dbEntityEntry.State = EntityState.Modified;  
  58.         }  
  59.   
  60.         public void Delete(T entity)  
  61.         {  
  62.             EntityEntry<T> dbEntityEntry = DbContext.Entry(entity);  
  63.             if (dbEntityEntry.State != (EntityState) EntityState.Deleted)  
  64.             {  
  65.                 dbEntityEntry.State = EntityState.Deleted;  
  66.             }  
  67.             else  
  68.             {  
  69.                 DbSet.Attach(entity);  
  70.                 DbSet.Remove(entity);  
  71.             }  
  72.         }  
  73.   
  74.         public void Delete(int id)  
  75.         {  
  76.             var entity = GetById(id);  
  77.             if (entity == nullreturn;  
  78.   
  79.             Delete(entity);  
  80.         }  
  81.     }  
  82.   

Now, below is the glimpse of the solution structure so far for my Movie Review SPA coming up using ASP.NET Core, WEB-API, Angular JS, Entity Framework and tons of new things.



I hope you  have liked this discussion. Thanks for joining me.