我正在开发一个asp.net mvc-5 web应用程序.我有两个模型类:-
public class ScanInfo
{
public TSServer TSServer { set; get; }
public Resource Resource { set; get; }
public List<ScanInfoVM> VMList { set; get; }
}
public class ScanInfoVM
{
public TSVirtualMachine TSVM { set; get; }
public Resource Resource { set; get; }
}
现在这两项行动是否相同?
Operation1
var vmlist = scaninfo.SelectMany(a => a.VMList).ToList();
if (vmlist.Any(a2 => a2.Resource.RESOURCENAME.ToLower() == vmname.ToLower()))
Operation2
if (scaninfo.Any(a=>a.VMList.Any(a2 => a2.Resource.RESOURCENAME.ToLower() == vmname.ToLower())))
还是会以不同的方式执行?
谢谢
发布于 2015-10-23 08:26:19
第一个选项有一个昂贵的操作,即使用SelectMany
来扁平列表元素。
除此之外,两者的作用应该是相同的。在找到第一场比赛时休息一下。
在数据库中的应用
如果在数据库上执行此查询,第一个选项是错误的,因为它将把所有数据带到应用程序内存中(因为您使用的是ToList
__),然后它将在内存对象中执行Any
检查。
第二个将在数据库端执行查询,并只将结果返回给应用程序。它不会将数据带回应用程序。
发布于 2015-10-23 08:53:35
不,他们会以不同的方式执行。
第一个更糟。它会使scaninfo被枚举,然后将所有ScanInfoVM放到一个列表中,然后使用Any
过滤ScanInfoVM。
第二个要好得多,但它正在检查是否存在与您的标准相匹配的ScanInfo
s。
简而言之,它们的执行方式不同,并且检查的东西略有不同,但是由于您只关心是否存在存在,那么它们应该会给出相同的结果,但是第二个结果会执行得更快,只从数据库返回一个布尔值,它将停止查找第一个布尔值,而您的第一个结果将从数据库返回所有内容,然后开始检查。
如果您只是在第一个操作中删除ToList()
,那么您需要运行一个分析器来确定性能更好的操作。我怀疑它们会以同样的方式执行,但这取决于数据库提供程序如何将表达式树转换为SQL,以及SQL服务器如何优化结果查询。
发布于 2015-10-23 09:04:30
var vmlist = scaninfo.SelectMany(a => a.VMList).ToList();
这将运行一个SQL查询,以获取与一个VMList
行关联的每个ScanInfo
行,为每个行构建一个VMList
对象,然后在内存中创建一个列表来存储它们。
if (vmlist.Any(a2 => a2.Resource.RESOURCENAME.ToLower() == vmname.ToLower()))
这将贯穿该列表,并为每一项计算出Resource.RESOURCENAME.ToLower() == vmname.ToLower()
是否为真(而不是回溯vmname.ToLower()
的值),并在找到匹配时立即返回true,如果从未找到匹配,则返回false。
if (scaninfo.Any(a=>a.VMList.Any(a2 => a2.Resource.RESOURCENAME.ToLower() == vmname.ToLower())))
这将在数据库上运行EXISTS
SQL查询,并相应地返回true
或false
。
我们通常认为这会更快,当然也会使用更少的内存。
https://stackoverflow.com/questions/33307078
复制