Если вы хотите создать своего собственного провайдера, вы должны знать, что это не так просто. Рассмотрим такие вещи, как вложенный выбор, вложенный где и т. Д. Есть отличные сообщений в блоге на эту тему.
Но вы заинтересованы в защите вашей базы данных от внедрения SQL. Так что, если вы посмотрите на пример кода на этой странице и методе VisitConstant
, это место, где вы сталкиваетесь с константами типа значения (string, int и т. Д.) Или IQueryable.
Защита от SQL-инъекций не сложна, вы просто создаете новый SQLParameter
или вызываете метод DbProviderFactory.CreateParameter
, описанный здесь . Вам понадобится некоторая коллекция для хранения ваших параметров во время обхода дерева выражений. Таким образом, модифицированный код будет выглядеть так:
protected override Expression VisitConstant(ConstantExpression c) {
IQueryable q = c.Value as IQueryable;
if (q != null) {
// assume constant nodes w/ IQueryables are table references
sb.Append("SELECT * FROM ");
sb.Append(q.ElementType.Name);
}
else if (c.Value == null) {
sb.Append("NULL");
}
else {
switch (Type.GetTypeCode(c.Value.GetType())) {
case TypeCode.Boolean:
param = dbProvider.CreateParameter();
param.Name = "@param" + paramsList.Count;
param.Value = (((bool)c.Value) ? 1 : 0;
paramsList.Add(param);
sb.Append(param.Name);
break;
case TypeCode.String:
param = dbProvider.CreateParameter();
param.Name = "@param" + paramsList.Count;
param.Value = c.Value; // you don't have to care about escaping or formatting
paramsList.Add(param);
sb.Append(param.Name);
break;
...
case TypeCode.Object:
throw new NotSupportedException(string.Format("The constant for '{0}' is not supported", c.Value));
default:
sb.Append(c.Value);
break;
}
}
return c;
}
Итак, пока вы просматриваете дерево выражений, вы строите строку SQL и собираете параметры SQL.