0

MSDN のドキュメントによると、LINQ クエリは foreach ループで繰り返される前に実行されません。

しかし、次のことを試すと:

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 プロファイラーを見ると、実際の SQL 呼び出しは、dataAdapter.Fill(dataSet)行を反復処理するときではなく、FillDataSet メソッドで呼び出すときに実行されることがわかります。

私の質問は次のとおりです。「a」で始まる名前のみで LINQ に SQL 実行を実行させるにはどうすればよいですか (FillDataSet メソッドの SQL commandText で指定せずに)。

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

正しい方向に導いてくれてありがとう。

4

2 に答える 2

3

これはまさに予期された動作です。ADO.NET を使用してデータを DataTable に取得し、ADO.NET の非接続アーキテクチャに沿って、基礎となるデータベースではなく、DataTable に対してクエリを実行しています。

LINQ クエリが最適化されたデータベース呼び出しにジャストインタイムで変換されることを確認したい場合は、LINQ to SQLなどを使用します。

于 2013-07-07T19:26:38.853 に答える
0

DataSet ではできません。唯一の方法は、DataSet/Table アダプターに限定された結果を入力することです (SQL で始まるものを記述する必要があります)。

于 2013-07-07T19:16:23.080 に答える