我可以找到很多关于如何更改表达式主体的信息,但是我找不到有关如何更改ReturnType的信息。
以下是我编写的代码,其中包含对下面给出的Convert例程的调用。
private T[] CheckCreatedOnDate<T>(Expression<Func<T, object>> fieldExpression, T[] input, Data.Context context) where T : Entity
{
var fieldDelegate = fieldExpression.Compile();
Expression<Func<T, bool>> predicateExpression = Convert(fieldExpression);
Func<T, bool> predicateDelegate = predicateExpression.Compile();
Predicate<T> predicate = predicateDelegate.Invoke;
DbSet<T> dbSet = context.Set<T>();
var data = dbSet.ToList();
foreach (T inputRecord in input)
{
var fieldObject = fieldDelegate.Invoke(inputRecord);
var dataRecord = data.SingleOrDefault(x => Equals(predicate, fieldObject));
if (dataRecord != null)
{
inputRecord.CreatedOn = dataRecord.CreatedOn;
}
}
return input;
}
此方法的行为应与EF中的AddOrUpdate方法非常相似,但是如果记录已经在Db中,则此方法只会替换createdOn日期。
但是我的代码仍无效。创建的谓词似乎不正确,因为它永远不会在Db中找到相关记录。
非常感谢。
干杯迈克
答案 0 :(得分:0)
假设fieldExpression
类似于(T e) => e.Field
,我得出结论,您希望在Field
列中找到具有相同值的DB记录。
试试这个:
foreach (T inputRecord in input)
{
object fieldObject = fieldDelegate.Invoke(inputRecord);
ParameterExpression p = fieldExpression.Parameters.First();
// Equivalent to x => x.Field == fieldObject
Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(
// input.Field == fieldObject
Expression.Equal(
// input.Field
fieldExpression.Body,
// constant from fieldObject
Expression.Constant(fieldObject)
),
new []{ p }
);
T dataRecord = dbSet.SingleOrDefault(predicate);
if (dataRecord != null)
{
inputRecord.CreatedOn = dataRecord.CreatedOn;
}
}
我通过获取fieldExpression
正文并将其传递给SingleOrDefault
调用,在每个循环运行中创建全新的谓词。