TECHNOLOGIES
FORUMS
JOBS
BOOKS
EVENTS
INTERVIEWS
Live
MORE
LEARN
Training
CAREER
MEMBERS
VIDEOS
NEWS
BLOGS
Sign Up
Login
No unread comment.
View All Comments
No unread message.
View All Messages
No unread notification.
View All Notifications
C# Corner
Post
An Article
A Blog
A News
A Video
An EBook
An Interview Question
Ask Question
DBSet.Find() API missing in Entity Framework Core Final RC1 Version
Rahul Sahay
Apr 05, 2016
6.7
k
0
0
facebook
twitter
linkedIn
Reddit
WhatsApp
Email
Bookmark
In this blog you will learn 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.
using
System;
using
System.Linq;
using
System.Linq.Expressions;
using
Microsoft.Data.Entity;
using
Microsoft.Data.Entity.Infrastructure;
namespace
MovieReviewSPA.Data.Helpers
{
public
static
class
Extensions
{
public
static
TEntity Find<TEntity>(
this
DbSet<TEntity>
set
,
params
object
[] keyValues) where TEntity :
class
{
var context = ((IInfrastructure<IServiceProvider>)
set
).GetService<DbContext>();
var entityType = context.Model.FindEntityType(
typeof
(TEntity));
var key = entityType.FindPrimaryKey();
var entries = context.ChangeTracker.Entries<TEntity>();
var i = 0;
foreach
(var property
in
key.Properties)
{
entries = Enumerable.Where(entries, e => e.Property(property.Name).CurrentValue == keyValues[i]);
i++;
}
var entry = entries.FirstOrDefault();
if
(entry !=
null
)
{
// Return the local object if it exists.
return
entry.Entity;
}
// TODO: Build the real LINQ Expression
// set.Where(x => x.Id == keyValues[0]);
var parameter = Expression.Parameter(
typeof
(TEntity),
"x"
);
var query = Queryable.Where(
set
, (Expression<Func<TEntity,
bool
>>)
Expression.Lambda(
Expression.Equal(
Expression.Property(parameter,
"Id"
),
Expression.Constant(keyValues[0])),
parameter));
// Look in the database
return
query.FirstOrDefault();
}
}
}
And, here is the completed Repository Pattern for my project.
using
System;
using
System.Linq;
using
Microsoft.Data.Entity;
using
Microsoft.Data.Entity.ChangeTracking;
using
MovieReviewSPA.Data.Contracts;
using
MovieReviewSPA.Data.Helpers;
using
DbContext = Microsoft.Data.Entity.DbContext;
using
EntityState = Microsoft.Data.Entity.EntityState;
namespace
MovieReviewSPA.Data
{
public
class
EFRepository<T> : IRepository<T> where T :
class
{
public
EFRepository(DbContext dbContext)
{
if
(dbContext ==
null
)
throw
new
ArgumentNullException(
"dbContext"
);
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
protected
DbContext DbContext {
get
;
set
; }
protected
DbSet<T> DbSet {
get
;
set
; }
public
virtual
IQueryable<T> GetAll()
{
return
DbSet;
}
public
virtual
T GetById(
int
id)
{
//EF Core Will be updated shortly with Find Extension by Default
//Here, I have written Extension method for the same
//Source:- http://stackoverflow.com/questions/29030472/dbset-doesnt-have-a-find-method-in-ef7/29082410#29082410
return
DbSet.Find(id);
}
public
virtual
void
Add(T entity)
{
EntityEntry<T> dbEntityEntry = DbContext.Entry(entity);
if
(dbEntityEntry.State != (EntityState) EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
}
public
virtual
void
Update(T entity)
{
EntityEntry<T> dbEntityEntry = DbContext.Entry(entity);
if
(dbEntityEntry.State != (EntityState) EntityState.Detached)
{
DbSet.Attach(entity);
}
dbEntityEntry.State = EntityState.Modified;
}
public
void
Delete(T entity)
{
EntityEntry<T> dbEntityEntry = DbContext.Entry(entity);
if
(dbEntityEntry.State != (EntityState) EntityState.Deleted)
{
dbEntityEntry.State = EntityState.Deleted;
}
else
{
DbSet.Attach(entity);
DbSet.Remove(entity);
}
}
public
void
Delete(
int
id)
{
var entity = GetById(id);
if
(entity ==
null
)
return
;
Delete(entity);
}
}
}
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.
DBSet.Find API missing
Entity Framework Core
Final RC1 Version
Next Recommended Reading
Login Page In MVC Using Entity Framework