如何将字符串转换为System.Linq.Expressions.Expression?Kendo Grid场景适配
Expression<Func<EventModel, bool>> in DAL Alright, let's work through how to turn that expression string you're passing from your controller into a usable Expression<Func<EventModel, bool>> in your DAL. The key thing here is that you shouldn't rely on the raw ToString() output of an expression—that's meant for debugging, not serialization. Instead, use a structured approach with libraries built for this exact purpose, or adjust how you pass the filter logic from controller to DAL.
Option 1: Use System.Linq.Dynamic.Core (Recommended)
This library is perfect for scenarios like this, especially with Kendo Grid since it plays nicely with dynamic filter strings. It lets you parse string-based Linq expressions directly into strongly-typed expressions.
Step 1: Set Up the Library
First, install the NuGet package in both your controller project and DAL project:
Install-Package System.Linq.Dynamic.Core
Step 2: Pass a Proper Filter String from Controller
Instead of converting the expression to a raw string with ToString(), generate a standard dynamic Linq filter string. If you're using Kendo's filter descriptors, you can even build this string directly from the request filters (avoiding the intermediate expression entirely if you want):
// In your controller using System.Linq.Dynamic.Core; // If you already have the expression, convert it to a dynamic Linq string // (You'll need the ExpressionTreeToString library to do this cleanly: Install-Package ExpressionTreeToString) var filterString = expression.ToString("DynamicLinq"); // Alternatively, build the string directly from Kendo's FilterRequest var filterDescriptors = request.Filters; // Your Kendo FilterDescriptor collection var filterString = BuildDynamicLinqFilter(filterDescriptors); // Write a simple extension method to map descriptors to string // Pass filterString to your DAL
Step 3: Parse the String in DAL
In your DAL, take the filter string and parse it back into an expression:
// In your DAL repository using System.Linq.Dynamic.Core; public IQueryable<EventModel> GetFilteredEvents(string filterString) { var dbContext = new YourDbContext(); var query = dbContext.Events; if (!string.IsNullOrWhiteSpace(filterString)) { // Parse the string into a strongly-typed expression var filterExpression = DynamicExpressionParser.ParseLambda<EventModel, bool>( parameters: null, expression: filterString ); query = query.Where(filterExpression); } return query; }
If You Already Have the Raw ToString() Output
If you can't change how you're passing the string (and you're stuck with something like x => x.EventName == "Conference"), you can clean it up to work with Dynamic Linq:
// In DAL var cleanedFilter = filterString.Substring(filterString.IndexOf("=>") + 2).Trim(); var filterExpression = DynamicExpressionParser.ParseLambda<EventModel, bool>(null, cleanedFilter);
⚠️ Note: This is fragile—ToString() output can change between .NET versions, so use this only as a temporary fix.
Option 2: Custom Serialization (Avoid Unless Necessary)
If you don't want to use third-party libraries, you can serialize the expression tree to JSON (or another format) and deserialize it back. This is more work because you have to handle all types of expression nodes (binary expressions, member accesses, etc.).
You can use Json.NET with a custom converter, but this requires writing a lot of code to map expression node types to JSON and back. For example:
// Example (simplified) JsonConverter for expressions public class ExpressionConverter : JsonConverter<Expression> { public override Expression ReadJson(JsonReader reader, Type objectType, Expression existingValue, bool hasExistingValue, JsonSerializer serializer) { // Logic to reconstruct expression from JSON nodes // This gets complex fast—you'll need to handle BinaryExpression, MemberExpression, etc. throw new NotImplementedException(); } public override void WriteJson(JsonWriter writer, Expression value, JsonSerializer serializer) { // Logic to serialize expression nodes to JSON throw new NotImplementedException(); } }
Unless you have strict requirements against third-party packages, this isn't worth the effort.
Key Takeaways
- Avoid using
Expression.ToString()for serialization—it's not designed for that. System.Linq.Dynamic.Coreis the easiest, most reliable choice for this scenario, especially with Kendo Grid's filtering system.- If you can, generate the dynamic Linq string directly from Kendo's filter request instead of going through an expression first.
内容的提问来源于stack exchange,提问作者user1996300

