2013-07-07 24 views
0

根據MSDN documentation,在foreach循環中迭代之前,不會執行LINQ查詢。當從數據庫中查詢數據時

但是,當我嘗試以下方法:

namespace MCSD487_AdoConnection 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      DataSet dataSet = new DataSet(); 
      dataSet.Locale = CultureInfo.InvariantCulture; 
      FillDataSet(dataSet); 

      DataTable folders = dataSet.Tables["Folder"]; 

      IEnumerable<DataRow> folderQuery = folders.AsEnumerable(); 

      IEnumerable<DataRow> aFolders = folderQuery.Where(f => f.Field<string>("Name")[0].ToString().ToLower() == "a"); 

      // this is where I thought the SQL execution whould happen 
      foreach (DataRow row in aFolders) 
      { 
       Console.WriteLine("{0} was created on {1}", row.Field<string>("Name"), row.Field<DateTime>("DateTime")); 
      } 

      Console.ReadLine(); 
     } 

     internal static void FillDataSet(DataSet dataSet) 
     { 
      try 
      { 
       string connectionString = ConfigurationManager.ConnectionStrings["conn"].ConnectionString; 

       SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT DateTime, Name FROM Folder", connectionString); 

       // Add table mappings. 
       dataAdapter.TableMappings.Add("Table", "Folder"); 
       dataAdapter.Fill(dataSet); 

       // Fill the DataSet. 
       // This it where the actual SQL executes 
       dataAdapter.Fill(dataSet); 
      } 
      catch (SqlException ex) 
      { 
       Console.WriteLine("SQL exception occurred: " + ex.Message); 
      } 
     } 
    } 
} 

,我看我的SQL Server Profiler中,我可以看到實際的SQL調用執行,當我打電話dataAdapter.Fill(dataSet)在FillDataSet方法,而不是進行遍歷時,通過行。我的問題是:如何讓LINQ僅對以'a'開頭的名稱執行SQL執行(沒有在FillDataSet方法的SQL commandText中指定)?

編輯2013年7月7日23:44: 我用以下解決方案結束後,根據埃文哈珀斯答案:

using System; 
using System.Data.SqlClient; 
using System.Linq; 
using System.Data.Linq; 
using System.Data.Linq.Mapping; 

namespace MCSD487_AdoConnection 
{ 
    [Table(Name = "Folder")] 
    public class Folder 
    { 
     private int _Id; 
     [Column(IsPrimaryKey = true, Storage = "_Id")] 
     public int Id 
     { 
      get { return _Id; } 
      set { _Id = value; } 
     } 

     private DateTime _DateTime; 
     [Column(Storage = "_DateTime")] 
     public DateTime DateTime 
     { 
      get { return _DateTime; } 
      set { _DateTime = value; } 
     } 

     private string _Name; 
     [Column(Storage = "_Name")] 
     public string Name 
     { 
      get { return _Name; } 
      set { _Name = value; } 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 

      DataContext db = new DataContext(new SqlConnection(@"Data Source=OLF\OLF;Initial Catalog=DirStructure;Integrated Security=True")); 

      Table<Folder> folders = db.GetTable<Folder>(); 

      IQueryable<Folder> folderQuery = from folder in folders 
              where folder.Name[0].ToString().ToLower() == "a" 
              select folder; 

      foreach (Folder folder in folderQuery) 
      { 
       Console.WriteLine("{0} was created on {1}", folder.Name, folder.DateTime); 
      } 

      Console.ReadLine(); 
     } 
    } 
} 

感謝指導我在正確的方向。

+0

如果您正在查詢啓用LINQ的數據源(EF,LINq-to-SQL等),***和***如果您使用的是'IQueryable '而不是'IEnumerable ' - *那麼*它可能做你想做的事。 –

回答

3

這正是預期的行爲。您正在使用ADO.NET將數據導入DataTable,然後根據ADO.NET的disconnected architecture查詢DataTable –而不是基礎數據庫–。

如果您希望將您的LINQ查詢轉換爲即時優化的數據庫調用,請使用類似LINQ to SQL的內容。

0

使用DataSet無法執行此操作。唯一的方法是用有限的結果填充DataSet/Table適配器(開始的東西必須用SQL編寫)。