Cho phép nói rằng tôi có một thứ gọi là Stuff trong cơ sở dữ liệu của tôi, với thuộc tính có tên là Id. Từ người dùng, tôi nhận được một chuỗi các đối tượng Range đã chọn (hoặc đúng hơn là tôi tạo chúng từ đầu vào của chúng) với các Id mà chúng muốn. Một phiên bản rút gọn của struct trông như thế này:C#, Linq2SQL: Tạo một vị từ để tìm các phần tử trong một số phạm vi
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;
}
...
}
Vì vậy, người ta có thể ví dụ đã nhận:
var selectedRange = new List<Range<int>>
{
new Range(1, 4),
new Range(7,11),
};
sau đó tôi muốn sử dụng để tạo ra một vị từ để chỉ chọn những thứ trong đó có một giá trị giữa chúng. Ví dụ, bằng cách sử dụng PredicateBuilder, tôi có thể ví dụ như làm điều đó theo cách này:
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);
}
và sau đó:
var stuff = datacontext.Stuffs.Where(predicate).ToList();
Những công trình! Những gì tôi muốn làm bây giờ, là tạo ra một phương pháp mở rộng chung để tạo ra những vị từ cho tôi. Loại như thế này:
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;
}
Vấn đề ở đây, là nó bị treo với một NotSupportedException do bộ chọn (ø) gọi: Method 'System.Object DynamicInvoke(System.Object[])' has no supported translation to SQL.
Tôi đoán đó là điều dễ hiểu. Nhưng có cách nào để giải quyết vấn đề này không? Những gì tôi muốn kết thúc với là vì vậy mà tôi chỉ có thể làm:
var stuff = datacontext.Stuffs.Where(selectedRange.ToPredicate<Stuff>(ø => ø.Id));
Hoặc thậm chí tốt hơn, tạo ra cái gì đó trả về một IQueryable vì vậy mà tôi chỉ có thể làm:
var stuff = datacontext.Stuffs.WhereWithin<Stuff>(selectedRange, ø => ø.Id); // Possibly without having to specify Stuff as type there...
Vì vậy, bất kỳ ý tưởng? Tôi thực sự muốn làm việc này, gây ra nếu không tôi sẽ nhận được rất nhiều những khối foreach mã, tạo vị ...
Lưu ý 1: Tất nhiên, sẽ thật tuyệt nếu tôi có thể mở rộng đến nhiều hơn int, như DateTime và như vậy, nhưng không chắc chắn làm thế nào mà kết thúc bằng cách sử dụng các toán tử> = và < = ... CompareTo có hoạt động với linq-to-sql không? Nếu không có vấn đề gì khi tạo hai. Một cho int và một cho DateTime, vì đó là chủ yếu là các loại này sẽ được sử dụng cho.
Lưu ý 2: Nó sẽ được sử dụng để báo cáo, nơi người dùng sẽ có thể thu hẹp những gì xuất hiện, dựa trên những thứ khác nhau. Giống như, tôi muốn báo cáo này cho những người đó và những ngày đó.
Làm cách nào có thể hoạt động với toàn bộ chuỗi đối tượng Phạm vi? –
Svish
Bạn có thể làm tương tự với OrElse ... Tôi sẽ cập nhật ... –
Và "x" này trong thông số của bạn là gì? – Svish