从数据库中查询数据时

本文关键字:数据 查询 数据库 | 更新日期: 2023-09-27 18:21:28

根据MSDN文档,在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调用是在调用FillDataSet方法中的dataAdapter.Fill(dataSet)时执行的,而不是在遍历行时执行的。

我的问题是:如何使LINQ仅对以"a"开头的名称执行SQL(而不在FillDataSet方法的SQL commandText中指定该名称)?

编辑2013-07-07 23:44:我最后给出了以下解决方案,基于Evan Harpers的回答:

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

谢谢你把我带向正确的方向。

从数据库中查询数据时

这正是预期的行为。您正在使用ADO.NET将数据获取到DataTable中,然后根据DataTable–而不是底层数据库–符合ADO.NET断开连接的体系结构。

如果您希望看到您的LINQ查询及时转换为优化的数据库调用,请使用类似LINQ to SQL的方法。

使用DataSet,您无法做到这一点。唯一的方法是用有限的结果填充DataSet/Table适配器(以stuff开头的部分必须用SQL编写)。