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”行。然后,第二部分应该更改 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();

}

另请注意,这不是更新多行的最有效方法,因为每次更新执行两个数据库请求。

于 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();
    }

澄清:事实上,我对“不起作用”部分并不完全正确。它if driveListis IQueryable,但它不会if it is IEnumerable(因为前者使用表达式,而后者 - 代表)。但是因为语法相同,所以很容易犯这个错误,所以你仍然不应该在 lambda 表达式中使用循环变量,而不管它们的真实类型。

于 2012-08-10T09:54:18.390 回答