I've been looking for a method to check if an object exists on the base, if it exists, execute a update
, if not, insert
.
I did not find anything that would answer me, so I made the following code:
public static void InsertOrUpdate<T>(this DbSet<T> dbSet, T entity) where T : class
{
PropertyInfo pId = entity.GetType().GetProperty("Id");
if (pId != null)
{
object valId = pId.GetValue(entity);
if (dbSet.Any(p => p.GetType().GetProperty("Id").GetValue(p).ToString() == valId.ToString()))
{
T e = dbSet.Where(p => p.GetType().GetProperty("Id").GetValue(p).ToString() == valId.ToString()).FirstOrDefault();
foreach (PropertyInfo p in e.GetType().GetProperties().Where(x => x.CanWrite && x.Name != "Id"))
{
p.SetValue(e, p.GetValue(entity));
}
dbSet.Update(e);
}
else
{
dbSet.Add(entity);
}
}
}
As I always read something about handling reflection, and I try to optimize the code, the question is simple:
Is there another way to do this method, or to improve this code?
At first, I have no problem with it, and it works perfectly. It's just a matter of not messing around and optimizing the code.
I'm using ASP.NET Core with Entity Framework Core and I have no practice with these.
Edit:
I've got this other method ( looks better but still has reflection
):
public static void InsertOrUpdate<T>(this ApplicationDbContext context, T entity) where T : class
{
PropertyInfo ps = entity.GetType().GetProperty("Id");
if (ps != null)
{
DbSet<T> set = context.Set<T>();
if (set.Any(x => ps.GetValue(x).ToString() == ps.GetValue(entity).ToString()))
{
context.Entry(entity).State = EntityState.Modified;
}
else
{
set.Add(entity);
}
}
}