首先,我应该首先承认我真的不太了解使用WMI或LINQ。因此,我确信任何人都不会感到惊讶,因为我有这么艰难的时刻!
麻烦的是我正在尝试从同一个WMI对象查询或返回多个值。通常情况下这不会很糟糕,但由于需要仅返回与特定数据集匹配的元素,因此我发现难以解决这个问题。问题是,我必须首先查询WMI以获取特定元素或值,然后重新启动查询,按所述元素或值过滤以返回所需的数据集。
我确信我可以遍历WMI对象中的所有元素并将它们附加到集合中。然后遍历集合直到我得到我正在寻找的东西,但后来我仍然有过滤掉所有额外不必要元素的问题。
所以我想我的问题是,对于WMI对象进行高级搜索的最佳方法是什么?如何优化流程以便检索我正在寻找的信息不需要这么长时间?
在我的多次搜索中,我发现了几个使用LINQ的人的引用,但我对LINQ的有限接触意味着我不确定如何在这个实例中使用它,所以任何帮助或见解都将非常感激。
这是我到目前为止所提出的:
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;
答案 0 :(得分:2)
所以我不熟悉您的特定数据库提供程序,但您的主要问题是您正在迭代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;
请注意,如果可能的话,您应该在数据库端进行排序,并将输出限制为数据库端的1个值。在不知道您正在使用的查询提供程序的细节的情况下,我无法说明这样做的最佳方式是什么。
答案 1 :(得分: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;
}