我需要在自己的代码中使用“Where”Linq功能。
让我解释一下:我们有一个应用程序,允许用户编写所谓的“用户代码”,这是C#中的代码,将由应用程序拾取并在运行时编译和运行。
在用户代码中,我需要能够指定SQL条件。特殊情况是日期列上的条件。我们可能有 [DateColumn] ='1/1/2001'等条件易于实现,但 [DateColumn] = GetDate()+ 1 。在后一种情况下,我需要实现一个解析器来“理解”表达式。我不想盲目地发送给用户输入的任何内容(避免 SQL注入)。
用户最乐意编写类似Linq的查询:
xxx.Where(field => field == new DateTime(2001, 1, 1));
xxx.Where(field => field == DateTime.Now.AddDays(1));
是否可以以任何方式利用Linq to SQL框架?我需要在后面生成的SQL进一步构造整个查询并将其发送到SQL Server。
是否有任何第三方工具可以帮助我?
我不需要整个IQueryable接口(编写,加入查询等)。只能将System.Linq.Expressions.Expression转换为T-SQL(即使有限制)。
什么是为SQL公开此转换功能的System.Linq。*命名空间?也许我可以用Reflector获得一些提示。
非常感谢。
答案 0 :(得分:2)
SDK中有一个名为dynamic linq的示例代码。
\ CS 2008 Samples \ LinqSamples \ DynamicQuery
你可以做这些事情:
Northwind db = new Northwind(connString);
db.Log = Console.Out;
var query =
db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("New(CompanyName as Name, Phone)");
另一种可能性是实现Custom Linq Provider。一个很好的例子可以在“THE WAYWARD WEBLOG”http://blogs.msdn.com/mattwar/pages/linq-links.aspx找到。这个博客帮助我实现了自己的自定义提供程序。
public interface IQueryable : IEnumerable {
Type ElementType { get; }
Expression Expression { get; }
IQueryProvider Provider { get; }
}
public interface IQueryProvider {
IQueryable CreateQuery(Expression expression);
IQueryable<TElement> CreateQuery<TElement>(Expression expression);
object Execute(Expression expression);
TResult Execute<TResult>(Expression expression);
}
答案 1 :(得分:0)
我想你可以利用Linq的懒惰评估来实现这个目标。如果我理解你的问题,我认为你可以做这样的事情;
// Before user code:
var products = from p in db.products select p;
// Insert user-generated code here, such as i.e.
userProducts = products.Where(p => price < 1000);
// After user code:
for (var product in userProducts)
{
Whatever(product);
}
由于linq是惰性的,因此在枚举“结果”之前,不会向数据库发出实际的SQL查询,在本例中为“userProducts”。
答案 2 :(得分:0)
在充分尊重的情况下,我认为你是从煎锅里跳出来的。您不希望允许SQL注入,但您允许代码注入。 C#代码,甚至是lambda,都可以产生副作用。
AFAIK,C#4.0允许您动态编译代码。但是您必须执行编译器质量分析以防止用户做一些愚蠢或恶意的事情。 更容易按摩WHERE子句以防止SQL注入。