基本思想是获取一个字符串并根据XML文件(或任何LINQed提供者)对其进行评估
我发现了LINQ Dynamic Query Library。只是粗略地浏览一下下载包中的单个文档。这似乎是添加扩展方法来参数化LINQ查询的各个部分。有谁知道这是否有动态评估?
有什么方法可以做(假设有一些方法可以使用XML文件中的数据为种子播种)?
ClassFromWishfulThinking.Evaluate(sLinqQuery);
答案 0 :(得分:3)
一定是可能的,因为Linqpad做到了!
看how it works page有点心灵弯曲,我不确定这是你想要用生产代码做什么,除非你真的无法避免它。
没有框架方法只能做你想要的东西,我可以说因为.net的工作原理而具有相当高的可信度。你必须像LinqPad一样使用csharpcodeprovider来调用编译器。
您可以更改Linq动态查询库以执行所需操作。
答案 1 :(得分:2)
我在VB中使用此代码来评估运行时字符串中包含的代码...您需要将其转换为C#,但没有理由您不能只传入包含LINQ表达式的字符串。您需要稍微修改FuncString以允许使用LINQ,因为我只引用System.Math。我在运行时使用它来评估(主要是数学)表达式,但我想它可以被修改/扩展以评估.NET框架中的任何东西......
Function Evaluate(ByVal Expression As String, ByVal Args() As Object) As Object
If Expression.Length > 0 Then
'Replace each parameter in the calculation expression with the correct values
Dim MatchStr = "{(\d+)}"
Dim oMatches = Regex.Matches(Expression, MatchStr)
If oMatches.Count > 0 Then
Dim DistinctCount = (From m In oMatches _
Select m.Value).Distinct.Count
If DistinctCount = Args.Length Then
For i = 0 To Args.Length - 1
Expression = Expression.Replace("{" & i & "}", Args(i))
Next
Else
Throw New ArgumentException("Invalid number of parameters passed")
End If
End If
Dim FuncName As String = "Eval" & Guid.NewGuid.ToString("N")
Dim FuncString As String = "Imports System.Math" & vbCrLf & _
"Namespace EvaluatorLibrary" & vbCrLf & _
" Class Evaluators" & vbCrLf & _
" Public Shared Function " & FuncName & "() As Double" & vbCrLf & _
" " & Expression & vbCrLf & _
" End Function" & vbCrLf & _
" End Class" & vbCrLf & _
"End Namespace"
'Tell the compiler what language was used
Dim CodeProvider As CodeDomProvider = CodeDomProvider.CreateProvider("VB")
'Set up our compiler options...
Dim CompilerOptions As New CompilerParameters()
With CompilerOptions
.ReferencedAssemblies.Add("System.dll")
.GenerateInMemory = True
.TreatWarningsAsErrors = True
End With
'Compile the code that is to be evaluated
Dim Results As CompilerResults = _
CodeProvider.CompileAssemblyFromSource(CompilerOptions, FuncString)
'Check there were no errors...
If Results.Errors.Count > 0 Then
Else
'Run the code and return the value...
Dim dynamicType As Type = Results.CompiledAssembly.GetType("EvaluatorLibrary.Evaluators")
Dim methodInfo As MethodInfo = dynamicType.GetMethod(FuncName)
Return methodInfo.Invoke(Nothing, Nothing)
End If
Else
Return 0
End If
Return 0
End Function
Sub Main()
'In a real application, this string would be loaded from a database
'it would be stored by some calculation administrator...
Dim Expr As String = " If ({0} < 20000) Then" & vbCrLf & _
" Return Max(15, Min(75,0.12*{0}))" & vbCrLf & _
" Else" & vbCrLf & _
" Return Max(75,0.05*{0})" & vbCrLf & _
" End If"
Dim Args As New List(Of String)
While True
'This value would be loaded from some data interpreter for inclusion
'in the calculation...
Dim Val As String = Console.ReadLine
Args.Clear()
If IsNumeric(Val) Then
Args.Add(Val)
Dim dblOut As Object = Evaluate(Expr, Args.ToArray)
Console.WriteLine(dblOut)
Else
Exit While
End If
End While
End Sub
没有理由你不能稍微修改函数定义,以便它可以作为字符串的扩展,以允许你像这样调用它:
Dim LinqString = "from c in myLinqData where c.SomeField.Equals(""somevalue"") select c"
Dim output = LinqString.Evaluate
答案 2 :(得分:0)
无论如何,大部分LinqToXml都是由字符串驱动的。例如,Elements extension method将获取一个字符串并查找具有该名称的所有子元素。
如果您的查询以字符串形式开始(而不是作为Queryable / Enumerable上的方法调用),那么它实际上不是一个linq查询 - 而是其他内容。也许XPath可以提供帮助。