我想要一个C#SingleOrNewIdentified(o => o.prop,value)函数,该函数负责在未找到Any(o.prop == value)时返回带有o.prop = value预设的新o.不幸的是,我对表达式和lambda的理解很差.
我经常发现自己需要以多次写入方式使用新的EF对象之前,唯一地设置一个标识符(例如emailAddress,oauthId,GUID,自然键).一次写入一次的任务通常使我以一种不太清楚的方式来拖尾一些块.
似乎可以做到,因为我会反思.但是,我不想以任何方式在此函数的使用者中击败类型检查.
也欢迎对此想法提出警告.
解决方法:
public static T SingleOrNewIdentified<T, TProp>(this IQueryable<T> queryable, Expression<Func<T, TProp>> propExpr, TProp value) where T : class, new()
{
var property = (PropertyInfo)((MemberExpression)propExpr.Body).Member;
var paramExpr = Expression.Parameter(typeof(T));
var eqExpr = Expression.Equal(Expression.Property(paramExpr, property), Expression.Constant(value));
var predicate = Expression.Lambda<Func<T, bool>>(eqExpr, paramExpr);
T maybe = queryable.SingleOrDefault(predicate);
if (maybe != null) return maybe;
T @default = new T();
property.SetValue(@default, value);
return @default;
}