一段SQL求高人改造为Linq.分不是问题

zyug 2012-11-08 10:37:21
最近写统计,发现一些统计就个人能力而言改选成Linq查询压力山大。
特别是如下的一些SQL语句
统计某天,某类型的计数。
小弟不才写了一段SQL,每次改变量。然后提交SQl语句去查
小弟的解决方案。每次执行SQL完之后转换成dynamic对象的一个列表

大致代码如下

string TypeTableName = "Source";
string TypeTableValue = "id";
string TypeTableText = "Title";

string QueryTableName = "AskReservation";
string QueryTypeForeignKey = "SourceId";
string QueryTableTimeField = "Addtime";


var QueryFilter = " " + QueryTableTimeField + " between '" + startdate + "' and '" + enddate + "' and companyId in(" + string.Join(",", companys) + ") and groupid in (" + string.Join(",", groups) + ") ";
var sql = " declare @tsql nvarchar(4000) " +
" set @tsql = '' " +
" select @tsql+= ',sum(case " + QueryTypeForeignKey + " when '+cast(" + TypeTableValue + " as nvarchar(20))+' then 1 else 0 end) as '+" + TypeTableText + "+' ' from " + TypeTableName + " where " + TypeTableValue + " in (select " + QueryTypeForeignKey + " from " + QueryTableName + " where " + QueryFilter + " group by " + QueryTypeForeignKey + ") " +
" set @tsql = 'select convert(char(10)," + QueryTableTimeField + ",120) as 日期' +@tsql + ' from " + QueryTableName + " where " + QueryFilter.Replace("'", "''") + " group by convert(char(10)," + QueryTableTimeField + ",120) order by convert(char(10)," + QueryTableTimeField + ",120) desc '" +
" exec(@tsql) ";

List<ExpandoObject> objects = ExecuteTSqlResults(sql,new Entities());





下面列出ExecuteTSqlResults方法


/// <summary>
/// 执行自定义查询语句,并返回动态对象
/// </summary>
/// <param name="tsql">查询语句</param>
/// <param name="context">执行上下文</param>
/// <returns>语句执行结果</returns>
public List<ExpandoObject> ExecuteTSqlResults(string tsql, ObjectContext context)
{
List<ExpandoObject> lists = new List<ExpandoObject>();
EntityConnection entityConnection = (EntityConnection)context.Connection;
DbConnection storeConnection = entityConnection.StoreConnection;
DbCommand command = storeConnection.CreateCommand();
command.CommandText = tsql;
bool openingConnection = command.Connection.State == ConnectionState.Closed;
if (openingConnection) { command.Connection.Open(); }
using (DbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
ExpandoObject t = new ExpandoObject();
for (int i = 0; i < reader.FieldCount; i++)
{
var dt = (IDictionary<string, object>)t;
if (!dt.Keys.Contains(reader.GetName(i)))
{
dt.Add(new KeyValuePair<string, object>(reader.GetName(i), reader.GetValue(i)));
}
else
{
int k = 1;
while (dt.Keys.Contains(string.Format("{0}({1})", reader.GetName(i), k)))
{
k++;
}
dt.Add(new KeyValuePair<string, object>(string.Format("{0}({1})", reader.GetName(i), k), reader.GetValue(i)));
}
}
lists.Add(t);
}
}
if (openingConnection && command.Connection.State == ConnectionState.Open) { command.Connection.Close(); }
return lists;
}



至于
为什么不用
foreach (DbDataRecord rec in new ObjectQuery<DbDataRecord>(myQuery, context))
我只能表示
ObjectQuery 不支持tsql 最多支持“select * from abc”
...全文
228 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
bdmh 2012-11-08
  • 打赏
  • 举报
回复
你这个表名啥的都是动态的,你还是用sql或存储过程去做吧
winner2050 2012-11-08
  • 打赏
  • 举报
回复
统计的代码复杂度高,性能敏感。 我都是直接用 sql 来执行。
冰镇宝贝321 2012-11-08
  • 打赏
  • 举报
回复
引用 6 楼 q107770540 的回复:
你的这种情况,可以使用表达式树来完成动态查询,类似这样: C# code1234567891011121314151617181920//依据IQueryable数据源构造一个查询IQueryable<Customer> custs = db.Customers;//组建一个表达式树来创建一个参数ParameterExpression param = Expre……
总能看到牛X的人啊
丰云 2012-11-08
  • 打赏
  • 举报
回复
linq是有统计语法的, 但你这个例子中很多内容都是动态的, 因此具体该怎么转成LINQ,还是得看你的业务, 至少目前提供的信息,让人难以把握。 好的优化都是针对业务的, 不仅仅是针对某部分代码的。
  • 打赏
  • 举报
回复
其实都不是问题,只是你问的是个问题,解决了就没问题,不解决始终是个问题
zyug 2012-11-08
  • 打赏
  • 举报
回复
引用 9 楼 q107770540 的回复:
dynamci linq: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
不失为一种思路 按此改写 1 代码量增大 2 代码可读性差了。
q107770540 2012-11-08
  • 打赏
  • 举报
回复


dynamci linq:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
q107770540 2012-11-08
  • 打赏
  • 举报
回复
http://www.cnblogs.com/lyj/archive/2008/03/25/1122157.html
MSDNXGH 2012-11-08
  • 打赏
  • 举报
回复
分是问题啊,问题是,我不会LINQ,只会ADO.NET
q107770540 2012-11-08
  • 打赏
  • 举报
回复
你的这种情况,可以使用表达式树来完成动态查询,类似这样:

//依据IQueryable数据源构造一个查询
IQueryable<Customer> custs = db.Customers;
//组建一个表达式树来创建一个参数
ParameterExpression param = 
    Expression.Parameter(typeof(Customer), "c");
//组建表达式树:c.ContactName
Expression selector = Expression.Property(param,
    typeof(Customer).GetProperty("ContactName"));
Expression pred = Expression.Lambda(selector, param);
//组建表达式树:Select(c=>c.ContactName)
Expression expr = Expression.Call(typeof(Queryable), "Select",
    new Type[] { typeof(Customer), typeof(string) },
    Expression.Constant(custs), pred);
//使用表达式树来生成动态查询
IQueryable<string> query = db.Customers.AsQueryable()
    .Provider.CreateQuery<string>(expr);
//使用GetCommand方法获取SQL语句
System.Data.Common.DbCommand cmd = db.GetCommand(query);
Console.WriteLine(cmd.CommandText);
patty1991 2012-11-08
  • 打赏
  • 举报
回复
打瓶酱油
kxloveh 2012-11-08
  • 打赏
  • 举报
回复
引用 2 楼 bdmh 的回复:
你这个表名啥的都是动态的,你还是用sql或存储过程去做吧
听版主的,
six-years 2012-11-08
  • 打赏
  • 举报
回复
难度高啊 sql 倒是做过 linq 。。。

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧