Tôi đang trong quá trình viết một lớp dữ liệu cho một phần của hệ thống của chúng tôi ghi nhật ký thông tin về các công việc tự động chạy mỗi ngày - tên công việc , nó kéo dài bao lâu, kết quả là gì, vvSử dụng LINQ ExpressionVisitor để thay thế các tham số nguyên thủy với tham chiếu thuộc tính trong biểu thức lambda
Tôi đang nói chuyện với cơ sở dữ liệu bằng Entity Framework, nhưng tôi đang cố giữ những chi tiết đó ẩn khỏi các mô-đun cấp cao hơn và tôi không muốn các đối tượng thực thể được phơi bày.
Tuy nhiên, tôi muốn làm cho giao diện của mình rất linh hoạt trong tiêu chí mà nó sử dụng để tra cứu thông tin công việc. Ví dụ: giao diện người dùng sẽ cho phép người dùng thực hiện các truy vấn phức tạp như "cung cấp cho tôi tất cả công việc có tên 'hello' chạy từ 10:00 sáng đến 11:00 sáng." Rõ ràng, điều này trông giống như một công việc cho các cây Expression
được tạo động.
Vì vậy, những gì tôi muốn lớp dữ liệu của tôi (kho) để có thể làm là chấp nhận LINQ biểu thức kiểu Expression<Func<string, DateTime, ResultCode, long, bool>>
(biểu thức lambda) và sau đó đằng sau hậu trường chuyển đổi đó lambda để một biểu thức Entity Framework ObjectContext
tôi có thể sử dụng dưới dạng bộ lọc bên trong mệnh đề Where()
.
Tóm lại, tôi đang cố chuyển đổi biểu thức lambda loại Expression<Func<string, DateTime, ResultCode, long, bool>>
thành Expression<Func<svc_JobAudit, bool>>
, trong đó svc_JobAudit
là đối tượng dữ liệu Khuôn khổ thực thể tương ứng với bảng nơi lưu trữ thông tin công việc. (Bốn thông số trong đại biểu đầu tiên tương ứng với tên của công việc, khi nó chạy, kết quả và khoảng thời gian đó đã lấy trong MS tương ứng)
Tôi đã đạt được tiến bộ rất tốt bằng cách sử dụng lớp ExpressionVisitor
cho đến khi tôi nhấn một bức tường gạch và nhận được một InvalidOperationException
với thông báo lỗi này:
Khi gọi từ 'VisitLambda', viết lại một nút kiểu 'System.Linq.Expressions.ParameterExpression' phải trả lại một giá trị null không của cùng loại. Ngoài ra, ghi đè 'VisitLambda' và thay đổi nó để không truy cập trẻ em thuộc loại này.
Tôi hoàn toàn bối rối. Tại sao heck nó sẽ không cho phép tôi chuyển đổi các nút biểu thức tham chiếu tham số đến các nút tham chiếu thuộc tính? Có cách nào khác để giải quyết vấn đề này không?
Dưới đây là một số mẫu mã:
namespace ExpressionTest
{
class Program
{
static void Main(string[] args)
{
Expression<Func<string, DateTime, ResultCode, long, bool>> expression = (myString, myDateTime, myResultCode, myTimeSpan) => myResultCode == ResultCode.Failed && myString == "hello";
var result = ConvertExpression(expression);
}
private static Expression<Func<svc_JobAudit, bool>> ConvertExpression(Expression<Func<string, DateTime, ResultCode, long, bool>> expression)
{
var newExpression = Expression.Lambda<Func<svc_JobAudit, bool>>(new ReplaceVisitor().Modify(expression), Expression.Parameter(typeof(svc_JobAudit)));
return newExpression;
}
}
class ReplaceVisitor : ExpressionVisitor
{
public Expression Modify(Expression expression)
{
return Visit(expression);
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node.Type == typeof(string))
{
return Expression.Property(Expression.Parameter(typeof(svc_JobAudit)), "JobName");
}
return node;
}
}
}
[Thay tham số trong biểu thức lambda] (http://stackoverflow.com/questions/11159697/replace-parameter-in-lambda-expression) –