[英]Converting Expression<Func<DTO,bool>> to Expression<Func<Domain, bool>>
[英]“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.