Tôi đang trong quá trình tạo một hệ thống lọc phức tạp hơn cho dự án lớn này của chúng ta. Một trong những vị từ chính là có thể vượt qua các so sánh thông qua một tham số chuỗi. Điều này thể hiện trong các hình thức sau đây: "> 50" hoặc "5-10" hoặc "< 123,2"Phương pháp mở rộng trả về biểu thức lambda thông qua so sánh
Những gì tôi có (như là một ví dụ để minh họa)
ViewModel:
TotalCost (string) (value: "<50")
Required (string) (value: "5-10")
EF mô hình:
TotalCost (double)
Required(double)
biểu mà tôi muốn sử dụng:
model => model.Where(field => field.TotalCost.Compare(viewModel.TotalCost) && field.Required.Compare(viewModel.Required));
biểu mà tôi muốn nhận:
model => model.Where(field => field.TotalCost < 50 && field.Required > 5 && field.Required < 10);
Hoặc một cái gì đó giống như rằng
Tuy nhiên ... Tôi không có ý tưởng bắt đầu từ đâu. Tôi đã thu hẹp nó xuống
public static Expression Compare<T>(this Expression<Func<T, bool>> value, string compare)
Nó có thể không chính xác, nhưng đây là tất cả những gì tôi có. Người xây dựng so sánh không phải là vấn đề, đó là một chút dễ dàng. Phần khó thực sự là trả lại biểu thức. Tôi chưa bao giờ thử trả về các biểu thức như các giá trị hàm. Vì vậy, về cơ bản những gì tôi cần phải giữ, là lĩnh vực và trả lại một biểu thức so sánh, khá nhiều.
Bất kỳ trợ giúp nào? : X
Cập nhật:
Alas này không giải quyết vấn đề của tôi. Có thể là vì tôi đã thức dậy trong 23 giờ qua, nhưng tôi không có manh mối nhỏ nào về cách biến nó thành một phương pháp mở rộng. Như tôi đã nói, những gì tôi muốn ... về cơ bản là một cách để viết:
var ex = new ExTest();
var items = ex.Repo.Items.Where(x => x.Cost.Compare("<50"));
Con đường tôi hình ra rằng chức năng (có thể là hoàn toàn sai) là
public static Expression<Func<decimal, bool>> Compare(string arg)
{
if (arg.Contains("<"))
return d => d < int.Parse(arg);
return d => d > int.Parse(arg);
}
Nó thiếu " giá trị này - để so sánh ở vị trí đầu tiên và tôi chưa tìm ra cách để có thể nhận được biểu thức đầu vào ... như đối với ReSharper, nó gợi ý tôi chuyển nó thành boolean thay thế ...
Đầu tôi đầy lông tơ tại thời điểm này ...
Cập nhật 2:
Tôi cố gắng tìm ra một cách để có một đoạn mã mà làm việc trong một kho lưu trữ bộ nhớ trên một ứng dụng console. Tôi chưa thử nó với Entity Framework.
public static bool Compare(this double val, string arg)
{
var arg2 = arg.Replace("<", "").Replace(">", "");
if (arg.Contains("<"))
return val < double.Parse(arg2);
return val > double.Parse(arg2);
}
Tuy nhiên, tôi rất nghi ngờ đó là những gì tôi là sau khi
Cập nhật 3:
Đúng vậy, sau khi ngồi xuống và nhìn qua biểu thức lambda một lần nữa, trước khi câu trả lời cuối cùng, tôi đi với một cái gì đó tương tự như sau, nó không điền vào các yêu cầu chính xác của "So sánh()" nhưng Đó là một 'quá tải-ish' Trường hợp phương pháp:
public static IQueryable<T> WhereExpression<T>(this IQueryable<T> queryable, Expression<Func<T, double>> predicate, string arg)
{
var lambda =
Expression.Lambda<Func<T, bool>>(Expression.LessThan(predicate.Body, Expression.Constant(double.Parse(50.ToString()))));
return queryable.Where(lambda);
}
Tuy nhiên, dù cho đôi mắt của tôi, tất cả mọi thứ dường như hợp lý, tôi nhận được ngoại lệ thời gian chạy của:
System.ArgumentException was unhandled
Message=Incorrect number of parameters supplied for lambda declaration
Source=System.Core
StackTrace:
at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters)
Đây là dòng thủ phạm rõ ràng:
var lambda =
Expression.Lambda<Func<T, bool>>(Expression.LessThan(predicate.Body, Expression.Constant(double.Parse(50.ToString()))));
Tôi rất gần với giải pháp. Nếu tôi có thể bị lỗi đó, tôi tin rằng EF có khả năng dịch nó thành SQL. Nếu không ... tốt, phản ứng cuối cùng có lẽ sẽ đi.
Tôi nghĩ rằng, đó là một phần Update2 của bạn sẽ không thực hiện đối với SQL Server (EF). Bạn đã thử chưa? –
Vâng, đúng vậy. Như tôi đã nghĩ tbh. – NeroS