- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一种感觉,我知道这种行为的原因是什么,但我不知道解决它的最佳方法是什么。
我已经构建了一个 LinqToSQL 查询:
public IEnumerable<AllConditionByCountry> GenerateConditions(int paramCountryId)
{
var AllConditionsByCountry =
(from cd in db.tblConditionDescriptions...
join...
join...
select new AllConditionByCountry
{
CountryID = cd.CountryID,
ConditionDescription = cd.ConditionDescription,
ConditionID = cd.ConditionID,
...
...
}).OrderBy(x => x.CountryID).AsEnumerable<AllConditionByCountry>();
return AllConditionsByCountry;
}
此查询返回大约 9500 多行数据。
我是这样从我的 Controller 调用它的:
svcGenerateConditions generateConditions = new svcGenerateConditions(db);
IEnumerable<AllConditionByCountry> AllConditionsByCountry;
AllConditionsByCountry = generateConditions.GenerateConditions(1);
然后我正在循环:
foreach (var record in AllConditionsByCountry)
{
...
...
...
这是我认为的问题所在:
var rList = AllConditionsByCountry
.Where(x => x.ConditionID == conditionID)
.Select(x => x)
.AsEnumerable();
我正在根据从上述查询中收集的数据进行嵌套循环(利用我从 AllConditionByCountry
获得的原始数据。我认为这就是我的问题所在。当它在做对数据的过滤,它会大大减慢。
基本上这个过程会写出一堆文件(.json、.html)我首先只使用 ADO.Net 对此进行了测试,运行所有这些记录大约需要 4 秒。使用 EF(存储过程或 LinqToSql)需要几分钟。
我应该对我正在使用的列表类型做些什么,或者这只是使用 LinqToSql 的代价吗?
我试过返回 List<AllConditionByCountry>
, IQueryable
, IEnumerable
来 self 的 GenerateConditions
方法。列表花了很长时间(类似于我现在看到的)。 IQueryable
当我尝试执行第二个过滤器时出现错误(查询结果不能多次枚举)。
我在 LinqPad 中运行了同样的 Linq 语句,它在不到一秒的时间内返回。
我很乐意添加任何其他信息。
请告诉我。
编辑:
foreach (var record in AllConditionsByCountry)
{
...
...
...
var rList = AllConditionsByCountry
.Where(x => x.ConditionID == conditionID)
.Select(x => x)
.AsEnumerable();
conditionDescriptionTypeID = item.ConditionDescriptionTypeId;
id = conditionDescriptionTypeID + "_" + count.ToString();
...
...
}
最佳答案
TL;DR:您对数据库进行了 9895 次查询,而不是一次。您需要重写您的查询,以便只执行一个查询。查看 IEnumerable 的工作原理以获得执行此操作的一些提示。
啊,是的,那个for
循环是你的问题。
foreach (var record in AllConditionsByCountry)
{
...
...
...
var rList = AllConditionsByCountry.Where(x => x.ConditionID == conditionID).Select(x => x).AsEnumerable();
conditionDescriptionTypeID = item.ConditionDescriptionTypeId;
id = conditionDescriptionTypeID + "_" + count.ToString();
...
...
}
Linq-to-SQL 的工作方式与 Linq 类似,因为它(粗略地说)将函数附加到链中,以便在迭代可枚举时执行 - 例如,
Enumerable.FromResult(1).Select(x => throw new Exception());
这实际上不会导致您的代码崩溃,因为永远不会迭代可枚举对象。 Linq-to-SQL 的运行原理类似。所以,当你定义这个时:
var AllConditionsByCountry =
(from cd in db.tblConditionDescriptions...
join...
join...
select new AllConditionByCountry
{
CountryID = cd.CountryID,
ConditionDescription = cd.ConditionDescription,
ConditionID = cd.ConditionID,
...
...
}).OrderBy(x => x.CountryID).AsEnumerable<AllConditionByCountry>();
您不是对数据库执行任何操作,您只是指示 C# 构建一个在迭代时执行此操作的查询。这就是为什么只声明这个查询很快。
当您进入 for 循环时,您的问题就来了。当您点击 for 循环时,您表示要开始迭代 AllConditionsByCountry
迭代器。这会导致 .NET 关闭并执行初始查询,这需要时间。
当您调用 AllConditionsByCountry.Where(x => x.ConditionID == conditionID)
时在 for 循环中,您正在构造另一个实际上不执行任何操作的迭代器。大概您实际上使用了 rList
的结果然而,在该循环中,您实际上是在构建要针对数据库执行的 N 个查询(其中 N 是 AllConditionsByCountry 的大小)。
这会导致您对数据库有效执行大约 9501 次查询 - 1 次用于初始查询,然后一次查询用于原始查询中的每个元素。与 ADO.NET 相比速度急剧下降是因为您可能比最初多进行了 9500 次查询。
理想情况下,您应该更改代码,以便对数据库执行一次且仅一次查询。您有几个选择:
重写 Linq-to-SQL 查询,使其看起来像这样
var conditions = AllConditionsByCountry.ToList();foreach(条件中的var记录){ var rList = conditions.Where(....);
请注意,在该示例中,我正在搜索 conditions
而不是 AllConditionsByCountry
- .ToList()
将返回一个已经迭代过的列表,因此您不会再创建任何数据库查询。这将仍然很慢(因为您在 9500 条记录上执行 O(N^2)),但它仍然比创建 9500 个查询快,因为它将全部在内存中完成。
我想我应该指出哪些方法会导致 IEnumerable 被迭代,哪些不会。
任何名为 As*
的方法(例如 AsEnumerable<T>()
)不会导致枚举被迭代。它本质上是一种从一种类型转换为另一种类型的方法。
任何名为 To*
的方法(例如 ToList<T>()
)将导致枚举被迭代。如果是 Linq-to-SQL,这也将执行数据库查询。任何也会导致您从可枚举中获取值的方法也会导致迭代。您可以通过创建查询并使用 ToList()
强制迭代来利用它。然后搜索该列表 - 这将导致比较在内存中完成,这就是我上面演示的内容
关于c# - IEnumerable 过滤时处理时间太长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51408399/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!