2012-08-10 135 views
1

有這個查詢::C# - SQL - LINQ查詢

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; 

並且該行可以識別它,但由於。(代碼如下),我需要整個查詢來識別它。 line

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的一行:\此計算機上。然後,第二部分應該更改FreeSpace值並將其替換爲從控制檯應用程序檢索到的新FreeSpace值。

任何反饋,將不勝感激,在此先感謝:)

+2

你想達到什麼目的?請向我們介紹您的問題和整個代碼,而不僅僅是記錄。 – 2012-08-10 09:37:31

+0

你有什麼「幾個問題」? – 2012-08-10 09:38:04

+0

你的查詢想要做什麼?看起來好像Linq可能不是您的最佳解決方案,但您不清楚代碼的用途。 – 2012-08-10 09:40:07

回答

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(); 
} 
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只是循環體中有效。解決方案是將大括號放在所有您希望在循環中運行的代碼中,並且您還需要將q更改爲q2

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

} 

還要注意,這不是更新多行的最有效方式,因爲每次更新都執行兩次數據庫請求。

+0

問題在於它刪減了查詢的結尾 – Ghostyy 2012-08-10 09:46:49

+0

@Ghostyy:「那個問題」? 「那」具體是什麼意思?你的意思是添加大括號?我不是說「也許你需要花括號,但我不完全確定」。我的意思是你真的*需要他們,而且我100%確定它。如果添加它們會給你帶來新的問題,那麼你也需要解決這些問題。你是什​​麼意思「刪除查詢結束」?你能顯示你的實際代碼和錯誤信息嗎? – 2012-08-10 09:50:53

+0

查詢的結尾是「ServerDrive existingServerDrives = q2.First(); existingServerDrives.FreeSpace = driveList [i] .FreeSpace;」 雖然我在整個上下文中放置大括號時出現錯誤消息,但「IO.DriveInfo不包含'FreeSpace'的定義」 – Ghostyy 2012-08-10 09:54:16

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

澄清:其實,我並不完全正確的關於「將不工作」的一部分。它如果driveListIQueryable,但它將不會如果它是IEnumerable(因爲前者使用表達式,後者 - 代表)。但是因爲語法是一樣的,所以這個錯誤非常容易,所以你不應該在lambda表達式中使用循環變量,不管它們的實際類型如何。

+0

「修復它的最簡單方法是將i值(或參考值)存儲在單獨的變量中。」我知道你不能在EF中這樣做,對linq2sql沒有把握。 +1指出來 – Thousand 2012-08-10 10:01:32

+0

@JaneDoe既沒有與Linq2Sql沒有EF不EF,這是C#問題。 – 2012-08-10 10:13:08

+0

@SergRogovtsev:這是關於LINQ和C#的。 – Ghostyy 2012-08-10 13:24:37