如何将 Expression<Func<T, object>> 转换为 Expression<Func<T, bool>>?
How do I convert Expression<Func<T, object>> to Expression<Func<T, bool>>?
我可以找到很多有关如何更改表达式主体的信息,但找不到有关如何更改 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 中找到相关记录。
非常感谢大家的帮助。
迈克干杯
假设 fieldExpression
类似于 (T e) => e.Field
我得出的结论是您希望在 Field
列中找到具有相同值的数据库记录。
试试这个:
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
调用。
我可以找到很多有关如何更改表达式主体的信息,但找不到有关如何更改 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 中找到相关记录。
非常感谢大家的帮助。
迈克干杯
假设 fieldExpression
类似于 (T e) => e.Field
我得出的结论是您希望在 Field
列中找到具有相同值的数据库记录。
试试这个:
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
调用。