2010-07-09 117 views
0

我想从使用linq的数据库的WCF服务获得序列化结果。wcf序列化linq结果导致大量的sql服务器负载

在数据库中的表进行归一化在一定程度上,我回用的,我最初使用Data.Linq.DataLoadOptions,就像斯科特Landford的博客与LINQ查询检索以及其他一些数据:http://codeexperiment.com/post/Returning-LINQ-to-SQL-Entities-From-WCF.aspx

这里是我的代码的一部分是相关的:

ServerDALDataContext db = new ServerDALDataContext(); 

    System.Data.Linq.DataLoadOptions dlo = new System.Data.Linq.DataLoadOptions(); 
    // get COMPETITOR_ENTRies data along with COMPETITION 
    dlo.LoadWith<COMPETITION>(e => e.COMPETITOR_ENTRies); 
    // get dividends for competitors along with COMPETITOR_ENTRies 
    dlo.LoadWith<COMPETITOR_ENTRY>(e => e.DIVIDENDs); 
    db.LoadOptions = dlo; 

    // retrieve MEETING data from database 
    var competitions = (from c in db.COMPETITIONs 
         select c) 
     .AsEnumerable() 
     .Where(c => c.CONTROL_UPDATE_DATA.FOR_UPDATE); 
      && c.COMPETITION_DATETIME.Value.Date == dateFrom.Date); 

    // return as list    
    return competitions != null ? competitions.ToList() : null; 

还存在占用业务,每10秒左右就可以发送异步请求WCF服务的客户端应用。

问题是,当使用它时,它实际上会超载SQL服务器以至于它始终使用100%的CPU,导致对客户端的响应迟到。我删除了dlo.LoadWith的调用和响应来了一个有意义的时间。

关于如何解决这个问题的任何建议,而不是重载SQL Server那么多?

+1

架构,索引,采样数据请。基本上你有糟糕的设计... – gbn 2010-07-09 12:05:28

+0

在这种情况下,什么是一个好方法?这就是我想要发现的。 – TheBoyan 2010-07-09 12:18:16

+0

向我们展示用表,索引和示例数据调用的SQL ...没有,我们会猜测... – gbn 2010-07-09 12:21:59

回答

1
// retrieve MEETING data from database 
var competitions = (from c in db.COMPETITIONs 
        select c) 
    .AsEnumerable() 
    .Where(c => c.CONTROL_UPDATE_DATA.FOR_UPDATE); 
     && c.COMPETITION_DATETIME.Value.Date == dateFrom.Date); 

AsEnumerable ...

你加载整个表。


什么是这种情况的好方法吗?

要么设置dataContext.Log = Console.Out;要么启动sql分析器并查看发送到数据库的内容。

从那里两种可能性:

  1. 您要发送到数据库中获取你想要的结果以及过滤查询 - 但他们都表现不佳。将查询放入SqlStudio中,然后单击“显示预计执行计划”按钮。同样使用SET STATISTICS IO ONSET STATISTICS TIME ON,然后查看消息选项卡。该解决方案通常涉及添加索引。

  2. 您正在发送严重筛选的查询或分段获取数据的查询(多次往返)。回到生成查询的c#代码,并找出错误是什么。解决方案通常包括正确放置位置,或者执行Join而不是GroupBy,并且在循环内绝对不执行查询。


正确的日期滤波与时间修剪:

DateTime theDate = DateTime.Now; 
    //manipulate date into a range locally. 
DateTime startDate = theDate.Date; 
DateTime endDate = startDate.AddDays(1); 

    //filter by the range - endpoint excluded. 
IEnumerable<Order> query = myDC.Orders.Where(order => 
    startDate <= order.OrderDate 
    && order.OrderDate < endDate);