如何使数据表识别功能

时间:2012-02-17 22:36:57

标签: c# asp.net function

我在某处找到了一个能够执行字符串方程的函数。例如,我可以有一个字符串,如“1 + 5”。当我将它传递给函数时,它返回返回的答案。在我的应用程序中,我从数据库中提取公式并将未知数字(例如x,y或z)替换为用户在使用应用程序时输入的实际数字(1,2,3,4,5等)。但是,我需要执行的一些公式需要平方根。当我尝试传递包含Math.Sqrt()函数的字符串时,它给出了一个错误,指出它是一个未定义的函数。有没有办法可以修改函数来识别这个函数?

该函数使用数据表。这是代码:

public static double executeFormula(string expression)
{
    System.Data.DataTable table = new System.Data.DataTable();
    table.Columns.Add("expression", string.Empty.GetType(), expression);
    System.Data.DataRow row = table.NewRow();
    table.Rows.Add(row);
    return double.Parse((string)row["expression"]);
}  

谢谢你们!

4 个答案:

答案 0 :(得分:3)

使用nCalc并完成它。

它完全支持你所说的内容,并且它可以扩展到那些尚未命中的内容。

答案 1 :(得分:2)

我害怕答案是否定的,正如你所写的那样。您正在展示的功能是利用数据表中的DataColumn功能Expression属性。

实际上,它支持您在SQL中找到的许多运算符:

来自文档:

OPERATORS

Concatenation is allowed using Boolean AND, OR, and NOT operators. You can use parentheses to group clauses and force precedence. The AND operator has precedence over other operators. For example:

(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'

When creating comparison expressions, the following operators are allowed:

<

>

<=

>=

<>

=

IN

LIKE

The following arithmetic operators are also supported in expressions:

+ (addition)

- (subtraction)

* (multiplication)

/ (division)

% (modulus)

STRING OPERATORS

To concatenate a string, use the + character. Whether string comparisons are case-sensitive or not is determined by the value of the DataSet class's CaseSensitive property. However, you can override that value with the DataTable class's CaseSensitive property.

WILDCARD CHARACTERS

Both the * and % can be used interchangeably for wildcards in a LIKE comparison. If the string in a LIKE clause contains a * or %, those characters should be escaped in brackets ([]). If a bracket is in the clause, the bracket characters should be escaped in brackets (for example [[] or []]). A wildcard is allowed at the beginning and end of a pattern, or at the end of a pattern, or at the beginning of a pattern. For example:

"ItemName LIKE '*product*'"

"ItemName LIKE '*product'"

"ItemName LIKE 'product*'"

Wildcards are not allowed in the middle of a string. For example, 'te*xt' is not allowed.

PARENT/CHILD RELATION REFERENCING

A parent table may be referenced in an expression by prepending the column name with Parent. For example, the Parent.Price references the parent table's column named Price.

A column in a child table may be referenced in an expression by prepending the column name with Child. However, because child relationships may return multiple rows, you must include the reference to the child column in an aggregate function. For example, Sum(Child.Price) would return the sum of the column named Price in the child table.

If a table has more than one child, the syntax is: Child(RelationName). For example, if a table has two child tables named Customers and Orders, and the DataRelation object is named Customers2Orders, the reference would be:

Avg(Child(Customers2Orders).Quantity)

AGGREGATES

The following aggregate types are supported:

Sum (Sum)

Avg (Average)

Min (Minimum)

Max (Maximum)

Count (Count)

StDev (Statistical standard deviation)

Var (Statistical variance).

Aggregates are usually performed along relationships. Create an aggregate expression by using one of the functions listed above and a child table column as detailed in PARENT/CHILD RELATION REFERENCING above. For example:

Avg(Child.Price)

Avg(Child(Orders2Details).Price)

不幸的是,Square Root不是您可以使用的功能之一。但是,当您使用DataTable时,您可以简单地遍历行,并直接从列值计算SquareRoot。想象一下,你有一个名为“MyNumber”的专栏。然后你可以做类似的事情:

myDataTable.Columns.Add(new DataColumn() { Name = "MySquareRoot", DataType = typeof(Double)});

foreach(DataRow row in myDataTable.Rows)
{
  myDataTable["MySquareRoot"] = Math.Sqrt(Convert.ToDouble(myDataTable["MyNumber"]));
}

如果您愿意,可以将此类函数放入Extension方法中。

或者,您可能希望在其他地方处理您的公式;您可以使用类,而不是使用DataTable来建模数据。类本身可以具有表示数据的属性(或列表或集合)以及对数据起作用的方法 - 然后您可以在C#中使用任何所需的函数。

答案 2 :(得分:0)

您可以创建人们能够识别和使用的“文本功能”,并且可以在程序中进行解析。请查看WolframAlphaMS Math 4.0。例如,您可以执行以下操作:

if(str.IndexOf("sqrt")>-1)
{
    //replace sqrt for the actual Math.Sqrt() function
}
祝你好运!

答案 3 :(得分:0)

查看CodePlex项目flee。 Flee允许您在运行时评估字符串表达式,例如"sqrt(a^2 + b^2)"