可以說我的數據庫中有一些名爲Stuff的東西,名爲Id。從用戶中,我得到了一系列選定的Range對象(或者我從他們的輸入中創建它們)和他們想要的ID。該結構的精簡版本是這樣的:C#,Linq2SQL:創建謂詞以查找多個範圍內的元素
public struct Range<T> : IEquatable<Range<T>>, IEqualityComparer<Range<T>>
{
public T A;
public T B;
public Range(T a, T b)
{
A = a;
B = b;
}
...
}
所以一個可能例如已經得到了:
var selectedRange = new List<Range<int>>
{
new Range(1, 4),
new Range(7,11),
};
然後我想用它來創建一個謂語只選擇其中有一個東西這些之間的價值。例如,使用PredicateBuilder,我可以舉例來說做到這一點是這樣的:
var predicate = PredicateBuilder.False<Stuff>();
foreach (Range<int> r in selectedRange)
{
int a = r.A;
int b = r.B;
predicate = predicate.Or(ø => ø.Id >= a && ø.Id <= b);
}
然後:
var stuff = datacontext.Stuffs.Where(predicate).ToList();
其中一期工程!我現在想要做的是創建一個通用的擴展方法來爲我創建謂詞。種類是這樣的:在這裏
public static Expression<Func<T,bool>> ToPredicate<T>(this IEnumerable<Range<int>> range, Func<T, int> selector)
{
Expression<Func<T, bool>> p = PredicateBuilder.False<T>();
foreach (Range<int> r in range)
{
int a = r.A;
int b = r.B;
p = p.Or(ø => selector(ø) >= a && selector(ø) <= b);
}
return p;
}
問題,是它與NotSupportedException異常崩潰,因爲選擇(O)調用:Method 'System.Object DynamicInvoke(System.Object[])' has no supported translation to SQL.
我想這是可以理解的。但是有什麼辦法可以解決這個問題嗎?我願與落得如此,我可能只是這樣做:
var stuff = datacontext.Stuffs.Where(selectedRange.ToPredicate<Stuff>(ø => ø.Id));
甚至更好,創造的東西,返回一個IQueryable,這樣我可以只是做:
var stuff = datacontext.Stuffs.WhereWithin<Stuff>(selectedRange, ø => ø.Id); // Possibly without having to specify Stuff as type there...
因此,任何想法?我真的很想得到這個工作,因爲如果不是我會得到這些代碼的foreach塊的不少,創建謂詞...
注1:當然,如果我能會很好擴展到比int更多,如DateTime等,但不知道如何最終使用> =和< =運算符... CompareTo是否與linq-to-sql一起使用?如果沒有,創建兩個沒有問題。一個用於int,另一個用於DateTime,因爲這主要是用於這個類型的類型。
注2:它將用於報告,用戶將能夠根據不同的事情縮小出現的範圍。比如,我希望這份報告適合那些人和那些日期。
這將如何與整個系列的範圍對象? –
Svish
2009-02-16 14:36:28
你可以用OrElse做同樣的...我會更新... – 2009-02-16 14:42:53