1

このクエリにはいくつかの問題があります::

var q2 =
    from sd in db.ServerDrives
    where sd.DriveLetter == driveList[i].Name
    select sd;
ServerDrive existingServerDrives = q.First();
existingServerDrives.FreeSpace = driveList[i].FreeSpace;
//..
db.SubmitChanges();

私の問題は、[i] への参照をどこに置くべきかわからないことです。

[i] の参照 ::

for (int i = 0; i < driveList.Count; i++)

私はそれを上に置くことができます、

existingServerDrives.FreeSpace = driveList[i].FreeSpace;

そして、行はそれを認識しますが、.(以下のコード) のためにそれを認識するためにクエリ全体が必要です。ライン

where sd.DriveLetter == driveList[i].Name;

どうすればこれができるか知っている人はいますか?

編集:完全なコード::

class Program
{
    List<DriveInfo> driveList = DriveInfo.GetDrives().Where(x => x.IsReady).ToList<DriveInfo>(); //Get all the drive info
    Server server = new Server();  //Create  the server object
    ServerDrive serverDrives = new ServerDrive();

    public static void Main()
    {
        Program c = new Program();
        c.RealDriveInfo();
        c.WriteInToDB();
    }

    public void RealDriveInfo()
    {


        //Insert information of one server - You will need get information of all servers
        server.ServerID = 0; //Here is necessery put PK key. I recommend doing the SQL server will automatically generate the PK.
        server.ServerName = string.Concat(System.Environment.MachineName);

        //Inserts information in the newServers object
        for (int i = 0; i < driveList.Count; i++)
        {

            //Put here all the information to object Server                
            serverDrives.DriveLetter = driveList[i].Name;
            serverDrives.TotalSpace = driveList[i].TotalSize;
            serverDrives.DriveLabel = driveList[i].VolumeLabel;
            serverDrives.FreeSpace = driveList[i].TotalFreeSpace;
            serverDrives.DriveType = driveList[i].DriveFormat;
            server.ServerDrives.Add(serverDrives);

        }
    }

    public void WriteInToDB()
    {
        //Add the information to an SQL Database using Linq.
        DataClasses1DataContext db = new DataClasses1DataContext(@"sqlserver");
        db.Servers.InsertOnSubmit(server);

        var q2 =
            from s in db.Servers
            where s.ServerName == "LAPTOP-043"
            select s;
        Server existingServers = q2.First();
        for (int i = 0; i < driveList.Count; i++)
            existingServers.ServerName = string.Concat(System.Environment.MachineName);
        //..
        for (int i = 0; i < driveList.Count; i++)
        {
            var q =
                from sd in db.ServerDrives
                where sd.DriveLetter == driveList[i].Name
                select sd;
            ServerDrive existingServerDrives = q.First();
            existingServerDrives.FreeSpace = driveList[i].FreeSpace;
            //..
            db.SubmitChanges();

私がやろうとしているのは、このコンピューターのドライブ C:\ と同じ 'DriveLetter' を含む行をクエリで検索することです。2 番目の部分では、FreeSpace の値を変更し、コンソール アプリケーションから取得した新しい FreeSpace の値に置き換えます。

フィードバックをお待ちしております。よろしくお願いします:)

4

3 に答える 3

3

あなたが何を言おうとしているのか、何をしようとしているのかわかりませんが、これはどうですか:

for (int i =0; i < driveList.Count; i++)
{
var q2 =
    from sd in db.ServerDrives
    where sd.DriveLetter == driveList[i].Name
    select sd;
ServerDrive existingServerDrives = q2.First();
existingServerDrives.FreeSpace = driveList[i].FreeSpace;
//..
db.SubmitChanges();
}
于 2012-08-10T09:37:37.660 に答える
2

Jane Doe は正しい考えを持っています。説明を追加するために、あなたの漠然とした説明から、あなたはこれを書いたようです:

for (int i = 0; i < driveList.Count; i++)
var q2 =
    from sd in db.ServerDrives
    where sd.DriveLetter == driveList[i].Name
    select sd;
ServerDrive existingServerDrives = q.First();
existingServerDrives.FreeSpace = driveList[i].FreeSpace;
//..
db.SubmitChanges();

これは次のように解釈されます。

for (int i = 0; i < driveList.Count; i++)
{
    var q2 =
        from sd in db.ServerDrives
        where sd.DriveLetter == driveList[i].Name
        select sd;
}

ServerDrive existingServerDrives = q.First();
existingServerDrives.FreeSpace = driveList[i].FreeSpace;
//..
db.SubmitChanges();

変数iはループ本体内でのみ有効です。解決策は、ループ内で実行したいすべてのコードを中括弧で囲みqq2.

for (int i = 0; i < driveList.Count; i++)
{
    var q2 =
        from sd in db.ServerDrives
        where sd.DriveLetter == driveList[i].Name
        select sd;

    ServerDrive existingServerDrives = q2.First();
    existingServerDrives.FreeSpace = driveList[i].FreeSpace;
    //..
    db.SubmitChanges();

}

また、更新ごとに 2 つのデータベース要求を実行するため、これは複数の行を更新する最も効率的な方法ではないことに注意してください。

于 2012-08-10T09:41:47.177 に答える
1

更新:閉鎖処理の詳細については、回答の最後にある説明をお読みください。

まず最初に。このコード:

    for (int i = 0; i < driveList.Count; i++)
    {
        var q =
            from sd in db.ServerDrives
            where sd.DriveLetter == driveList[i].Name
            select sd;
        //...
   }

中括弧に関係なく機能しません。その理由はi(面白い LINQ 構文によってマスクされている) の閉鎖です。iこれを修正する最も簡単な方法は、値 (または参照される値) を別の変数に格納することです。

    for (int i = 0; i < driveList.Count; i++)
    {
        var j = i;
        var q =
            from sd in db.ServerDrives
            where sd.DriveLetter == driveList[j].Name
            select sd;
        //...
    }

これは機能しますが、ルーズに見えます。より良い:

    for (int i = 0; i < driveList.Count; i++)
    {
        var drive = driveList[i];
        var q =
            from sd in db.ServerDrives
            where sd.DriveLetter == drive.Name
            select sd;
        ServerDrive existingServerDrives = q.First();
        existingServerDrives.FreeSpace = drive.FreeSpace;
        //..
        db.SubmitChanges();
    }

しかし、そもそもなぜループが必要なのでしょうか? なぜforeachですか?

    foreach (var drive in driveList)
    {
        var q =
            from sd in db.ServerDrives
            where sd.DriveLetter == drive.Name
            select sd;
        ServerDrive existingServerDrives = q.First();
        existingServerDrives.FreeSpace = drive.FreeSpace;
        //..
        db.SubmitChanges();
    }

しかし、これもうまくいきません。注意してください。閉鎖と同じ問題。解決策は簡単です:

    foreach (var d in driveList)
    {
        var drive = d;
        var q =
            from sd in db.ServerDrives
            where sd.DriveLetter == drive.Name
            select sd;
        ServerDrive existingServerDrives = q.First();
        existingServerDrives.FreeSpace = drive.FreeSpace;
        //..
        db.SubmitChanges();
    }

しかしもちろん、そのようなことはプロジェクションの方が優れています。

    foreach (var d in driveList.Select(d => new {freeSpace = d.FreeSpace, existingServerDrives = db.ServerDrives.First(sd => sd.DriveLetter == d.Name)}))
    {
        d.existingServerDrives.FreeSpace = d.freeSpace;
        //..
        db.SubmitChanges();
    }

明確化:実際、「うまくいかない」部分については完全に正しいわけではありません。である場合はそうなりますが、そうである場合はそうではありません(前者は式を使用し、後者はデリゲートを使用するため)。ただし、構文が同じであるため、このエラーが発生しやすいため、実際の型に関係なく、ラムダ式内でループ変数を使用しないでください。driveListIQueryableIEnumerable

于 2012-08-10T09:54:18.390 に答える