簡體   English   中英

“或”一起表達 <Func<EntityFramework Entity, bool> &gt;在.NET 4中,Silverlight RIA域服務

[英]“Or” Together Expression<Func<EntityFramework Entity, bool>> in .NET 4, Silverlight RIA domain service

我有一個小的自定義對象定義為:

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

我將List classID,List startTimes和List endTimes傳遞給RIA域服務函數。 作為組織問題,我將這些值分組到TimeSeriesDefinitions列表中,然后嘗試使用foreach循環創建一個表達式,該表達式將在類中的值與每個類之間的OR運算符之間選擇AND運算符,或者實現“ 。任何“我在下面收到的第一個答案所建議的查詢。 問題是我不能在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);

任何人都能指出我正確的方向嗎? 我想我可能會以某種方式將這整個事物構建成一個查詢字符串,但我寧願不去那里。

提前感謝您的見解!

可以使用List<Tuple<int, DateTime, DateTime>>代替List<TimeSeriesDefinition> 您的查詢將是這個......

return ObjectContext.EventLog.Where(c =>
           reporters.Any(r =>
               c.reporterID == r.Item1 &&
               c.reportDateTime >= r.Item2 &&
               c.reportDateTime <= r.Item3));

如果您對客戶端上的TimeSeriesDefinition的引用進行Funcletize(本地化),您應該能夠將它們包含在查詢中(請參閱此處的Evaluator.PartialEval方法http://msdn.microsoft.com/en-us/library/bb546158 .aspx )。 您應該能夠在Expression對象上簡單地調用它,並將對TimeSeriesDefinitions的引用提升為原始常量:

Evaluator.PartialEval(lambdaExpression);

至於你的編譯問題:

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

該作業的左側是通用的LambdaExpression。 右邊的一邊是BinaryExpression。 要進行賦值,您需要Lambda the 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));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM