2

まず、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;
4

2 に答える 2

2

したがって、私はあなたの特定のDBプロバイダーに精通していませんが、あなたの主な問題はIEnumerable、データベースに対して10回の異なるクエリを意味する10回反復していることです。あなたは確かにそれをする必要はありません、そしてそれはあなたのパフォーマンスを本当に殺します。また、返されたデータを10回ソートしています。あなたは一度だけそれをするべきです。

アイテムを1回フェッチしてから、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;

可能であれば、DB側で並べ替えを行い、出力をDB側で1つの値に制限する必要があることに注意してください。使用しているクエリプロバイダーの詳細を知らなければ、それを行うための好ましい方法が何であるかを言うことができませんでした。

于 2013-01-04T20:21:31.527 に答える
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;
}
于 2013-01-04T20:54:01.707 に答える