Tech
News
Videos
Forums
Jobs
Books
Events
More
Interviews
Live
Learn
Training
Career
Members
Blogs
Challenges
Certification
Contribute
Article
Blog
Video
Ebook
Interview Question
Collapse
Feed
Dashboard
Wallet
Learn
Achievements
Network
Rewards
SharpGPT
Premium
Contribute
Article
Blog
Video
Ebook
Interview Question
Register
Login
DBSet.Find() API missing in Entity Framework Core Final RC1 Version
WhatsApp
Rahul Sahay
8y
6.8
k
0
0
25
Blog
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
Up Next
Login Page In MVC Using Entity Framework
Ebook Download
View all
Diving Into ASP.NET WebAPI
Read by 21.4k people
Download Now!
Learn
View all
Membership not found