我有一个小的自定义对象,定义为:

public class TimeSeriesDefinition
{
    public int classID;
    public DateTime startTime;
    public DateTime endTime;
}


我正在将一个列表classID,一个列表开始时间和一个列表结束时间传递到RIA域服务函数中。就组织而言,我将这些值分组为TimeSeriesDefinitions列表,然后尝试使用foreach循环创建一个表达式,该表达式将使用AND运算符在一个类中的值之间进行选择,而每个运算符在每个类之间进行选择,或者实现一个“我收到的第一个答案所建议的“ .any”查询。问题是我不能在DomainService函数中使用TimeSeriesDefinition类,因为它不是原始类型或我的实体类型之一(也许我应该只用这种类型创建实体?),所以我需要另一种实现方法所需的查询结果。我最初使用的表达式的初衷是:

        Expression<Func<EventLog, bool>> bounds;
        Boolean assignedBounds = false;
        foreach (TimeSeriesDefinition ts in reporters)
        {
            if (assignedBounds.Equals(false))
            {
                bounds = c => c.reporterID == ts.classID && c.reportDateTime >= ts.startTime && c.reportDateTime <= ts.endTime;
                assignedBounds = true;
            }
            else
            {
                Expression<Func<EventLog, bool>> newBounds = c => c.reporterID == ts.classID && c.reportDateTime >= ts.startTime && c.reportDateTime <= ts.endTime;
                bounds = Expression.Or(Expression.Invoke(bounds), Expression.Invoke(newBounds);
                // bounds = Expression<Func<EventLog, bool>>.Or(bounds, newBounds);
            }
        }

        return this.ObjectContext.EventLog.Where(bounds);


我的目标是使结果集具有ts.startDate和ts.EndDate之间的ts.classID的所有记录。根据我在网上找到的信息,确保正确分配参数似乎也很棘手,但是现在我仍然得到

“无法将类型'System.Linq.Expressions.BinaryExpression'隐式转换为'System.Linq.Expressions.Expression>'”

线路错误

 bounds = Expression.Or(Expression.Invoke(bounds), Expression.Invoke(newBounds);


有人能指出我正确的方向吗?我想我可能可以将整个东西以某种方式构建到查​​询字符串中,但我不想去那里。

预先感谢您的见解!

最佳答案

如果在客户端上对TimeSeriesDefinition的引用进行功能化(本地化),则应该能够在查询中包括它们(请参见此处http://msdn.microsoft.com/en-us/library/bb546158.aspx中的Evaluator.PartialEval方法)。您应该能够简单地在Expression对象上调用它,并将对TimeSeriesDefinitions的引用提升为原始常量:

Evaluator.PartialEval(lambdaExpression);


至于你的编译问题:

bounds = Expression.Or(Expression.Invoke(bounds), Expression.Invoke(newBounds);


该分配的左侧是通用LambdaExpression。右手边是BinaryExpression。要进行分配,您需要La或Or,还需要为InvocationExpressions提供ParameterExpression:

var parameterExpression = Expression.Parameter(typeof(EventLog));
bounds = Expression.Lambda<Func<EventLog, bool>>(
    Expression.Or(
         Expression.Invoke(bounds, parameterExpression),
         Expression.Invoke(newBounds, parameterExpression),
    parameterExpression);


但是...您可能会遇到一个奇妙的事实,即RIA不支持InvocationExpressions ...(我尚未对此进行验证,但我知道EF不支持)。您必须扩展InvocationExpressions以内联它们(类似于上面提到的Funcletlizer)。

LINQKit(http://www.albahari.com/nutshell/linqkit.aspx)提供了一个开箱即用的功能。如上所述,它还提供了用于组合条件的辅助方法。如果您不希望完全依赖LINQKit,则可以在此处获取同一内容的源代码:http://www.java2s.com/Open-Source/CSharp/Content-Management-Systems-CMS/Kooboo/Microsoft/Data/Extensions/DataExtensions.cs.htm

然后只需将您的位置更改为:

return this.ObjectContext.EventLog.Where(InvocationExpander.Expand(bounds));

10-06 07:43
查看更多