public static class EFCoreExtensions
{
public static int Update<TEntity>(this IQueryable<TEntity> query, TEntity entity)
{
if (query == null) { return 0; }
if (entity == null) { return 0; }
var methods = typeof(SetPropertyCalls<TEntity>).GetMethods().Where(x => x.Name.ToLower() == "SetProperty".ToLower());
var setProperty = methods.FirstOrDefault();
foreach (var method in methods)
{
var ps = method.GetParameters();
if (ps.Length != 2)
{
continue;
}
if (ps[1].ParameterType.IsGenericType)
{
continue;
}
setProperty = method;
}
var entityExpression = Expression.Parameter(typeof(TEntity), "a");
var setPropertyExpression = Expression.Parameter(typeof(SetPropertyCalls<TEntity>), "x");
Expression call = setPropertyExpression;
var setCount = 0;
foreach (var p in typeof(TEntity).GetProperties())
{
var value = p.GetValue(entity);
if (value == null)
{
continue;
}
if (value is DateTime && ((DateTime)value) == DateTime.MinValue)
{
continue;
}
setCount++;
var propertyMethod = p.GetGetMethod();
var propertyExpression = Expression.Lambda(Expression.Property(entityExpression, propertyMethod), new[] { entityExpression });
call = Expression.Call(call,
setProperty.MakeGenericMethod(value.GetType()),
propertyExpression,
Expression.Constant(value));
}
if (setCount == 0) { return 0; }
var lambda = Expression.Lambda<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>>(call, setPropertyExpression);
return RelationalQueryableExtensions.ExecuteUpdate(query, lambda);
}
}