2 回答
TA贡献1813条经验 获得超2个赞
问题类似于无法转换基本属性的 LINQ 表达式和如何在 EF Core 表达式中使用继承的属性?,但在这种情况下, 和DeclaringType
都ReflectedType
指向MemberInfo
接口ISomeable
而不是实际的类。
这又在某种程度上让场景中的 EF Core 感到困惑Select
。我检查了最新的 EF Core 3.0 预览版,它也不起作用。您可以考虑将其发布到他们的问题跟踪器。
到目前为止,我可以提供的唯一解决方法是使用自定义后处理表达式ExpressionVisitor
并将成员访问器绑定到实际的类。像这样的东西:
public static partial class ExpressionUtils
{
public static Expression<T> FixMemberAccess<T>(this Expression<T> source)
{
var body = new MemberAccessFixer().Visit(source.Body);
if (body == source.Body) return source;
return source.Update(body, source.Parameters);
}
class MemberAccessFixer : ExpressionVisitor
{
protected override Expression VisitMember(MemberExpression node)
{
if (node.Expression != null && node.Expression.Type != node.Member.DeclaringType)
{
var member = node.Expression.Type.GetMember(node.Member.Name).Single();
if (member.ReflectedType != member.DeclaringType)
member = member.DeclaringType.GetMember(member.Name).Single();
return Expression.MakeMemberAccess(node.Expression, member);
}
return base.VisitMember(node);
}
}
}
现在
var someCriteria2 = GetCriteria<MySimpleEntity>().FixMemberAccess();
将生成与工作编译时表达式完全相同的表达式someCriteria,并且没有客户端评估。
注意:您仍然需要约束class,以避免上一个问题中的转换问题并使此解决方法发挥作用。
TA贡献1804条经验 获得超2个赞
我认为你的代码的问题是
GetCriteria<MySimpleEntity>();
linq
无法直接翻译sql
或没有直接翻译。如果你想使用它。执行ToList()
然后添加.Where(someCriteria2).ToList();
. 在观察者中,它认为/评估它是相同的。但在查询本身中,生成 sql 似乎并不是这样工作的。
我还经历过,在我的DateTime
扩展方法中,即使将其转换为string
我的扩展Where
方法,我也必须在linq
查询之外执行它并添加它
var dateUtc = DateTime.UtcNow.ExtensionMethod()
;
...Where(x => x.Date >= dateUtc
)
或者我在我的和/或FirstorDefault, First, ToList()
之前先执行select
where
- 2 回答
- 0 关注
- 94 浏览
添加回答
举报