Это не обязательно идеальное решение, но проект MetaLinq предоставляет сериализуемые оболочки для классов выражений LINQ.
Вот пример того, как вы можете воссоздать и выполнить выражение после его повторной сериализации.
Сначала мы сериализовали существующее выражение lamba в документ xml.
var originalExpr = EditableExpression.CreateEditableExpression<string, bool>(
str => str.Length > 3);
var serializer = new XmlSerializer(originalExpr.GetType());
string xml;
using (var writer = new StringWriter())
{
serializer.Serialize(writer, originalExpr);
xml = writer.ToString();
}
Затем мы десериализовали, развернули и скомпилировали его обратно в делегат, готовый к выполнению.
EditableExpression newExpr;
using (var reader = new StringReader(xml))
{
newExpr = (EditableExpression) serializer.Deserialize(reader);
}
var expr = (Expression<Func<string, bool>>) newExpr.ToExpression();
var items = new[] {"one", "two", "three"};
var result = items.Count(expr.Compile());
Debug.Assert(result == 1);
Так выглядит сериализованное выражение.
<EditableLambdaExpression xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<NodeType>Lambda</NodeType>
<TypeName>System.Func`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</TypeName>
<Body xsi:type="EditableBinaryExpression">
<NodeType>GreaterThan</NodeType>
<TypeName>System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</TypeName>
<Left xsi:type="EditableMemberExpression">
<NodeType>MemberAccess</NodeType>
<Expression xsi:type="EditableParameterExpression">
<NodeType>Parameter</NodeType>
<TypeName>System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</TypeName>
<Name>str</Name>
</Expression>
<MemberName>System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Int32 Length</MemberName>
</Left>
<Right xsi:type="EditableConstantExpression">
<NodeType>Constant</NodeType>
<Value xsi:type="xsd:int">3</Value>
</Right>
</Body>
<Parameters>
<EditableExpression xsi:type="EditableParameterExpression">
<NodeType>Parameter</NodeType>
<TypeName>System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</TypeName>
<Name>str</Name>
</EditableExpression>
</Parameters>
</EditableLambdaExpression>