C# 使用Linq优化WMI查询
首先,我应该首先承认,我真的不太了解如何使用WMI或LINQ来解决这个问题。因此,我相信我在这方面遇到了如此困难,这不会让任何人感到惊讶 问题是我试图从同一个WMI对象查询或返回多个值。通常情况下,这不会很糟糕,但我发现很难对其进行反复思考,因为只需要返回与特定数据集匹配的元素。问题是,我必须首先查询特定元素或值的WMI,然后重新启动查询,按所述元素或值过滤以返回所需的数据集 我确信我可以循环遍历WMI对象中的所有元素并将它们附加到集合中。然后在集合中循环,直到我得到我想要的东西,但是我仍然需要过滤掉所有多余的不必要的元素 所以我想我的问题是,对WMI对象进行高级搜索的最佳方法是什么?如何优化该过程,以使检索我要查找的信息不会花费太长时间 在我的多次搜索中,我发现了一些关于使用LINQ的人的参考资料,但我对LINQ的接触有限,这意味着我不确定在这种情况下如何使用它,因此非常感谢任何帮助或见解 以下是我到目前为止的想法:C# 使用Linq优化WMI查询,c#,linq,optimization,query-optimization,wmi,C#,Linq,Optimization,Query Optimization,Wmi,首先,我应该首先承认,我真的不太了解如何使用WMI或LINQ来解决这个问题。因此,我相信我在这方面遇到了如此困难,这不会让任何人感到惊讶 问题是我试图从同一个WMI对象查询或返回多个值。通常情况下,这不会很糟糕,但我发现很难对其进行反复思考,因为只需要返回与特定数据集匹配的元素。问题是,我必须首先查询特定元素或值的WMI,然后重新启动查询,按所述元素或值过滤以返回所需的数据集 我确信我可以循环遍历WMI对象中的所有元素并将它们附加到集合中。然后在集合中循环,直到我得到我想要的东西,但是我仍然需要
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true");
IEnumerable<ManagementObject> objects = searcher.Get().Cast<ManagementObject>();
string description = (from o in objects orderby o["IPConnectionMetric"]
select o["Description"].ToString()).FirstOrDefault();
_NICINDEX = (from o in objects orderby o["IPConnectionMetric"]
select o["Index"].ToString()).FirstOrDefault();
_MACADDRESS = (from o in objects orderby o["IPConnectionMetric"]
select o["MACAddress"].ToString()).FirstOrDefault();
_IPADDRESS = (from o in objects orderby o["IPConnectionMetric"]
select o["IPAddress"].ToString()).FirstOrDefault();
_IPV6ADDRESS = (from o in objects orderby o["IPConnectionMetric"]
select o["IPAddress"].ToString()).FirstOrDefault();
_SUBNETMASK = (from o in objects orderby o["IPConnectionMetric"]
select o["IPSubnet"].ToString()).FirstOrDefault();
_GATEWAY = (from o in objects orderby o["IPConnectionMetric"]
select o["DefaultIPGateway"].ToString()).FirstOrDefault();
_DNSSERVER = (from o in objects orderby o["IPConnectionMetric"]
select o["DNSServerSearchOrder"].ToString()).FirstOrDefault();
_DNSSECSVR = (from o in objects orderby o["IPConnectionMetric"]
select o["DNSServerSearchOrder"].ToString()).FirstOrDefault();
return description;
ManagementObjectSearcher search=新的ManagementObjectSearcher
(“从Win32_NetworkAdapter配置中选择*,其中IPEnabled=true”);
IEnumerable objects=searcher.Get().Cast();
字符串描述=(从对象orderby o[“IPConnectionMetric”]中的o开始)
选择o[“Description”].ToString()).FirstOrDefault();
_NICINDEX=(从对象orderby o[“IPConnectionMetric”]
选择o[“Index”].ToString()).FirstOrDefault();
_MACADDRESS=(从对象orderby o[“IPConnectionMetric”]中的o开始)
选择o[“MACAddress”].ToString()).FirstOrDefault();
_IPADDRESS=(从对象orderby o[“IPConnectionMetric”]中的o开始)
选择o[“IPAddress”].ToString()).FirstOrDefault();
_IPV6ADDRESS=(从对象orderby o[“IPConnectionMetric”]中的o开始)
选择o[“IPAddress”].ToString()).FirstOrDefault();
_SUBNETMASK=(从对象orderby o[“IPConnectionMetric”]中的o开始)
选择o[“IPSubnet”].ToString()).FirstOrDefault();
_网关=(从对象orderby o[“IPConnectionMetric”]
选择o[“DefaultIPGateway”].ToString()).FirstOrDefault();
_DNSSERVER=(从对象orderby o[“IPConnectionMetric”]中的o开始)
选择o[“DNSServerSearchOrder”].ToString()).FirstOrDefault();
_DNSSECSVR=(从对象orderby o[“IPConnectionMetric”]中的o开始)
选择o[“DNSServerSearchOrder”].ToString()).FirstOrDefault();
返回说明;
所以我不熟悉您的特定DB提供程序,但您的主要问题是您将IEnumerable
迭代了10次,这意味着对数据库进行了10次不同的查询。你当然不需要这样做,这真的会扼杀你的表现。您还对返回的数据进行了10次不同的排序;你应该只做一次
下面是对代码的重构,以获取该项一次,然后从中获取10个不同的值:
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true");
ManagementObject managementObject = searcher.Get()
.Cast<ManagementObject>()
.OrderBy(obj => obj["IPConnectionMetric"])
.FirstOrDefault();
string description = managementObject["Description"];
_NICINDEX = managementObject["Index"];
//repeat for the other 8 values following the above pattern
return description;
ManagementObjectSearcher search=新的ManagementObjectSearcher
(“从Win32_NetworkAdapter配置中选择*,其中IPEnabled=true”);
ManagementObject ManagementObject=searcher.Get()
.Cast()
.OrderBy(obj=>obj[“IPConnectionMetric”])
.FirstOrDefault();
字符串描述=管理对象[“描述”];
_NICINDEX=managementObject[“Index”];
//按照上述模式对其他8个值重复上述步骤
返回说明;
请注意,如果可能的话,您应该在DB端进行排序,并且在DB端将输出限制为仅1个值。如果不知道您正在使用的查询提供程序的详细信息,我就说不出更好的方法是什么。创建WMI查询以获取所需的数据,将其转换为LINQ to Objects查询,然后迭代结果,获取所需的数据位会更容易
var queryStr =
"SELECT * " +
"FROM Win32_NetworkAdapterConfiguration " +
"WHERE IPEnabled = true";
using (var searcher = new ManagementObjectSearcher(queryStr))
using (var managementQuery = searcher.Get())
{
// convert to LINQ to Objects query
var query =
from ManagementObject mo in managementQuery
orderby Convert.ToUInt32(mo["IPConnectionMetric"])
select new
{
Description = Convert.ToString(mo["Description"]),
Index = Convert.ToString(mo["Index"]),
MACAddress = Convert.ToString(mo["MACAddress"]),
IPAddress = String.Join(", ", (string[])mo["IPAddress"] ?? new string[0]),
IPSubnet = String.Join(", ", (string[])mo["IPSubnet"] ?? new string[0]),
DefaultIPGateway = String.Join(", ", (string[])mo["DefaultIPGateway"] ?? new string[0]),
DNSServerSearchOrder = String.Join(", ", (string[])mo["DNSServerSearchOrder"] ?? new string[0]),
};
// grab the fields
String description = null;
foreach (var item in query)
{
description = description ?? item.Description;
_NICINDEX = _NICINDEX ?? item.Index;
_MACADDRESS = _MACADDRESS ?? item.MACAddress;
_IPADDRESS = _IPADDRESS ?? item.IPAddress;
_IPV6ADDRESS = _IPV6ADDRESS ?? item.IPAddress;
_SUBNETMASK = _SUBNETMASK ?? item.IPSubnet;
_GATEWAY = _GATEWAY ?? item.DefaultIPGateway;
_DNSSERVER = _DNSSERVER ?? item.DNSServerSearchOrder;
_DNSSECSVR = _DNSSECSVR ?? item.DNSServerSearchOrder;
// check if all fields are set so we can stop
if (new[] { description, _NICINDEX, _MACADDRESS, _IPADDRESS, _IPV6ADDRESS, _SUBNETMASK, _GATEWAY, _DNSSERVER, _DNSSECSVR }.All(x => x != null))
break;
}
}
虽然我不清楚为什么要单独获取每个字段的第一个字段。我希望您希望第一个适配器的字段作为一个整体。所以最后,我认为最终应该是:
var first = query.FirstOrDefault();
if (first != null)
{
description = first.Description;
_NICINDEX = first.Index;
_MACADDRESS = first.MACAddress;
_IPADDRESS = first.IPAddress;
_IPV6ADDRESS = first.IPAddress;
_SUBNETMASK = first.IPSubnet;
_GATEWAY = first.DefaultIPGateway;
_DNSSERVER = first.DNSServerSearchOrder;
_DNSSECSVR = first.DNSServerSearchOrder;
}
基于您正在寻找的信息。。你认为“花这么长时间”是什么,其实你正在努力实现。如果您只想返回描述,那么为什么代码中包含所有其他内容呢?您确实意识到您正在执行10个单独的DB查询,因为这是您在
IQueryable
对象上迭代的次数。您还可以提取数据的整个结果集,对其进行10次不同的排序,然后获取相同的第一个值,10次不同的排序。说实话,返回并不重要,它只是我设置函数的方式,这不是我尝试的唯一查询。这里重要的一点是,因为我在WMI上执行了太多的查询,这导致我的应用程序速度明显减慢。真的,我只是想找一个更好的方法来做同样的事情。还有他目前不应该编译的代码,因为所有命名的变量都没有正确声明。。还在等着OP说出他真正想做的事。。如果这些值(例如_DNSSECSVR)被声明为局部变量,请拍摄您正在使用的方法定义或方法。这种未优化的方法更好的方法是创建一个自定义类,并传入您需要的值。最好用较小的c分隔并执行操作