我有一个Web应用程序(c#中的ASP.NET 4.0),我正在构建一个伪Adhoc组件。该组件允许用户从预定类别列表中选择(汽车制造,护理模型,汽车配件等)。用户可以根据需要选择多个类别,然后按“过滤器”按钮,该按钮将选择所选类别并将其发送到具有每个类别选项的新表单。每个类别都有多个选项。
实施例: 用户选择汽车颜色,汽车配件。
过滤器页面显示一个表格,其中包含预先填充了Car Color颜色的下拉列表。表单显示卫星广播的复选框,皮革内部的另一个复选框等。所有这些值都是预定义的。一旦用户指定了他们可以过滤的所有项目,我使用Linq查询数据库。就像现在一样,Linq查询针对的是一个当前包含14个左外连接的视图,如果没有过滤,则返回超过30,000行。
我正在使用动态linq来查询数据库链接,所以:
var data = CMS.Model.Adhoc.GetData().AsQueryable(); //must be AsQueryablefor Dynamic Linq to function
public static List<ViewADHOCContractInfo> GetData()
{
PortalDataContext db = new PortalDataContext(AuthenticatedUser.ConnectionString);
return db.ViewADHOCInfos.Select(x=>x).Distinct().ToList();
}
注意GetData()返回结果集的所有行和所有列,我认为这不是最有效的方法,更多的是在底部。
从那里开始,我对发送的过滤器执行FOREACH语句,并最小化每次迭代的结果集,如下所示(缩写):
foreach (Filters filter in filters.OrderBy(x=>x.strOrderNumber))
{
SanatizeFilter(filter.strFilter,filter);
if (filter.strValue != string.Empty && filter.strValue != null)
{
if (filter.strOperator == "Contains")
{
data = data.Where(filter.strFilter + "!= NULL and " + filter.strFilter + ".Contains(@0)", filter.strValue).
Select(x => x).ToList().AsQueryable();
}
else
{
data = data.Where(filter.strFilter + FormatOperator(filter.strOperator) + "@0", filter.strValue).
Select(x => x).ToList().AsQueryable();
}
}
}
所有这一切都很好,但速度很慢。我的第一个问题是,我如何使用Linq来减少这一点。我已经尝试了几种方法,只将来自过滤器的数据转换为变量“data”作为预填充的方式,但是我无法使用.AsQueryable()。我希望能够从过滤器对象中获取列标识符,并且只选择数据库中的列标识符,这样我就不必处理所有开销,但是我找不到一个允许我使用的解决方案。做这个,有什么想法吗?
第二个问题现在这是数据库中的所有视图,将它移动到函数或存储过程会更快/更有效吗? Linq可以与存储过程进行交互吗?
提前致谢
答案 0 :(得分:1)
嗯,您的问题可以分为两部分:
1)我的linq-2-sql方法是否良好
2)我的数据库是否接近良好
第一部分可以通过分析发送到数据库的SQL来解决。这将显示实际执行的查询/查询。正如您在评论中看到的那样,通过在方法的早期使用ToList(),这可能远非最佳。数据库非常适合过滤和处理大量数据。所以让他们做他们最擅长的事情!
现在问题的第二部分是关于视图的。使用存储过程等会更快吗?回答你的一部分问题:是的,Linq-2-sql也可以使用存储过程。但是如果你使用存储过程来检索太多数据,它仍然会很慢。这是DBA的故事部分。也许基表上的一些索引就足够了。另一种方法是向视图添加聚簇索引,然后将其实现。
我建议您先处理linq-2-sql部分:确保实际执行的sql是基于集合,并且所有过滤都在数据库中完成。如果它仍然太慢,请转到数据库层并查看可以在那里改进的内容。