C# Expressiontree到SQL的通用解析

C# Expressiontree到SQL的通用解析,c#,sql,linq,expression-trees,C#,Sql,Linq,Expression Trees,所以,我有一个非常简单的linq提供程序,它在一个小的受限域中处理对象。不需要完整的Linq2Sql实现,但我需要做的一些事情涉及sql查询。我的想法是,如果不看表名和列名,大多数表达式树=>sql必须非常(非常)通用 Expression<Func<DateTime, bool>> expr = d => d.DateTime.Month == 1 或 希望你明白我的意思。有这样的通用sql生成器吗?你应该看看Matt Warren的及其相关文章。呵呵,我们不是

所以,我有一个非常简单的linq提供程序,它在一个小的受限域中处理对象。不需要完整的Linq2Sql实现,但我需要做的一些事情涉及sql查询。我的想法是,如果不看表名和列名,大多数表达式树=>sql必须非常(非常)通用

Expression<Func<DateTime, bool>> expr = d => d.DateTime.Month == 1


希望你明白我的意思。有这样的通用sql生成器吗?

你应该看看Matt Warren的及其相关文章。

呵呵,我们不是很喜欢黑客吗?所以,它还没有完全工作,我需要弄清楚如何动态注入一些映射信息,但到目前为止,它看起来很有希望

我已经能够生成这个sql

SELECT t0.[Born], t0.[Yo]
FROM [Heies] AS t0
WHERE ((MONTH(t0.[Born]) = 1) OR (NOT (t0.[Yo] IS NULL OR t0.[Yo] = '') AND (t0.
[Born] = @p0)))
使用此代码

var provider = new DbEntityProvider(new SqlConnection(), new TSqlLanguage(), new ImplicitMapping(), new QueryPolicy());
var exp = provider.GetTable<Hey>().Where(d => d.Born.Month == 1 || (!String.IsNullOrEmpty(d.Yo) && d.Born == DateTime.Now)).Expression;
var sql = ((QueryProvider)provider).GetQueryText(exp);
var provider=new DbEntityProvider(new SqlConnection()、new tsqlanguage()、new ImplicitMapping()、new QueryPolicy());
var exp=provider.GetTable().Where(d=>d.Born.Month==1 | |(!String.IsNullOrEmpty(d.Yo)&&d.Born==DateTime.Now)).Expression;
var sql=((QueryProvider)provider.GetQueryText(exp);
使用IQToolkit,感谢Damian再次提醒我!如果有人有类似的方法通过Linq2Sql生成sql,我很乐意听到你的消息,这样我就可以摆脱对IQToolkit的依赖

更新

在做了很多傻事之后,我已经在提取每个参数的值方面碰壁了。经过大量的源代码读取,它似乎隐藏得很远,以便实际执行查询。好吧,你猜怎么着,我不想执行查询:/

在研究了Linq2Sql之后,我提出了这段代码,它的功能大致相同,所以也许我应该继续使用它

var xml = Generate<NewsProperty>();
var mapping = XmlMappingSource.FromUrl(xml);
var ctx = new DataContext(new SqlConnection("..."), mapping);

var query = ctx.GetTable<NewsProperty>().Where(n => n.Date.Year == 2010).OrderBy(n => n.Date).Take(5);
var cmd = ctx.GetCommand(query);
string sql = cmd.CommandText;

foreach (DbParameter param in cmd.Parameters)
{
   sql = sql.Replace(param.ParameterName, param.Value.ToString());
}
var xml=Generate();
var-mapping=XmlMappingSource.FromUrl(xml);
var ctx=newdatacontext(newsqlconnection(“…”),映射);
var query=ctx.GetTable().Where(n=>n.Date.Year==2010).OrderBy(n=>n.Date).Take(5);
var cmd=ctx.GetCommand(查询);
字符串sql=cmd.CommandText;
foreach(cmd.Parameters中的DbParameter参数)
{
sql=sql.Replace(param.ParameterName,param.Value.ToString());
}

我不明白为什么不使用Linq2SQL。有一千种不同的原因,但一个关键问题是,我在运行时之前不知道表名和列名,因此无法创建dbml模式来传递给Linq2SQL。很明显,您看不到这一点,因为看不到这一点。我并不是在问如何解决我的特定领域问题,因为它工作得很好,我很高兴使用表达式树来处理简单的东西,比如OrderBy方法。对于类似这样的情况,我有点紧张,因为它们可能会变得任意复杂,重新发明解析为sql的轮子似乎很愚蠢,因为大多数情况下,如果它是如此通用的话。@PauliØsterø:即使在运行时不知道表名和列名,仍然可以使用LINQ to sql。我使用运行时创建的表达式树设计并开发了一个动态报表生成器,我让LINQ to SQL为我解析为SQL。它很有效,已经投入生产近两年了。也许我应该调查一下。。。我一直认为Linq2Sql做得有点过火,而我真正需要的是将Where表达式转换成Sql。我不允许任何像连接、投影之类的高级东西,只是:)实际上我知道IQueryable工具包,我一直在研究应该能够从表达式发出sql的SqlFormatter类。也许我应该获取源代码并删除它对ORM工具的所有依赖,然后在我自己的代码中使用它。
SELECT t0.[Born], t0.[Yo]
FROM [Heies] AS t0
WHERE ((MONTH(t0.[Born]) = 1) OR (NOT (t0.[Yo] IS NULL OR t0.[Yo] = '') AND (t0.
[Born] = @p0)))
var provider = new DbEntityProvider(new SqlConnection(), new TSqlLanguage(), new ImplicitMapping(), new QueryPolicy());
var exp = provider.GetTable<Hey>().Where(d => d.Born.Month == 1 || (!String.IsNullOrEmpty(d.Yo) && d.Born == DateTime.Now)).Expression;
var sql = ((QueryProvider)provider).GetQueryText(exp);
var xml = Generate<NewsProperty>();
var mapping = XmlMappingSource.FromUrl(xml);
var ctx = new DataContext(new SqlConnection("..."), mapping);

var query = ctx.GetTable<NewsProperty>().Where(n => n.Date.Year == 2010).OrderBy(n => n.Date).Take(5);
var cmd = ctx.GetCommand(query);
string sql = cmd.CommandText;

foreach (DbParameter param in cmd.Parameters)
{
   sql = sql.Replace(param.ParameterName, param.Value.ToString());
}