在我的(C# + SQL Server)应用程序中,用户将能够定义数据规则,例如:
ITEM_ID = 1
OR (ITEM_NAME LIKE 'something' AND ITEM_PRICE > 123
AND (ITEM_WEIGHT = 456 OR ITEM_HEIGHT < 789))要验证的项目集总是不同的,但它们不是一个很大的数字。但是,规则的数量很多(假设是100000)。
我如何检查哪些规则验证了(还考虑到性能)给定的一组数字?
发布于 2011-08-09 04:50:57
您可以使用一些Microsoft自己的T-SQL解析引擎。
您可以在程序集Microsoft.Data.Schema.ScriptDom.dll和Microsoft.Data.Schema.ScriptDom.Sql.dll中找到它们。
TSql100Parser parser = new TSql100Parser(false);
IList<ParseError> errors;
Expression expr = parser.ParseBooleanExpression(
new StringReader(condition),
out errors
);
if (errors != null && errors.Count > 0)
{
// Error handling
return;
}如果没有得到任何错误,则该字符串是一个有效的过滤器表达式。尽管可能会有一些有害的表达。
如果您愿意,您可以通过您自己的访问器运行表达式来检测任何不需要的构造(例如子查询)。但请注意,对于Visit(...)和ExplicitVisit(...),您必须覆盖几乎所有的650重载。分部类在这里是很好的。
当您感到满意时,然后可以构建一个完整的SELECT语句,其中包含所有表达式:
var schemaObject = new SchemaObjectName();
schemaObject.Identifiers.Add(new Identifier {Value = "MyTable"});
var queryExpression = new QuerySpecification();
queryExpression.FromClauses.Add(
new SchemaObjectTableSource {SchemaObject = schemaObject});
// Add the expression from before (repeat as necessary)
Literal zeroLiteral = new Literal
{
LiteralType = LiteralType.Integer,
Value = "0",
};
Literal oneLiteral = new Literal
{
LiteralType = LiteralType.Integer,
Value = "1",
};
WhenClause whenClause = new WhenClause
{
WhenExpression = expr, // <-- here
ThenExpression = oneLiteral,
};
CaseExpression caseExpression = new CaseExpression
{
ElseExpression = zeroLiteral,
};
caseExpression.WhenClauses.Add(whenClause);
queryExpression.SelectElements.Add(caseExpression);
var selectStatement = new SelectStatement {QueryExpression = queryExpression};..。并将其转换回一个字符串:
var generator = new Sql100ScriptGenerator();
string query;
generator.GenerateScript(selectStatement, out query);
Console.WriteLine(query);输出:
SELECT CASE WHEN ITEM_ID = 1
OR (ITEM_NAME LIKE 'something'
AND ITEM_PRICE > 123
AND (ITEM_WEIGHT = 456
OR ITEM_HEIGHT < 789)) THEN 1 ELSE 0 END
FROM MyTable如果这个表达式太大而无法处理,您总是可以将规则拆分成块,以便同时运行几个块。
但是,要被允许重新分发Microsoft.Data.Schema.ScriptDom.*.dll文件,您必须拥有Visual Studio Team System的许可证(这至少包含在VS /旗舰版中吗?)
链接:http://blogs.msdn.com/b/gertd/archive/2008/08/22/redist.aspx
https://stackoverflow.com/questions/6985892
复制相似问题