linq2sql から linq2entities および ADO.net Entity Framework (ここでは L2E と呼びます) に移行したい人向けのリファレンスを開始したいと思います。これら 2 つのどちらが優れているかを議論したいわけではありません。どちらか一方から他方に移行したい人のために、これら 2 つの違いのリストを作成したいだけです。
基本的なことは簡単です。linq2sql データ クラスを削除し、ado.net モデル (データベースから作成) を追加します。「Entities」の名前を以前のデータ コンテキストの名前に変更します。
L2Sでの変更を永続化(保存)する
using (MyDataClassesDataContext mydc = new MyDataClassesDataContext())
{
// change data
mydc.SubmitChanges();
}
L2E では、これを次のように変更する必要があります。
using (MyDataClassesDataContext mydc = new MyDataClassesDataContext())
{
// change data
mydc.SaveChanges();
}
L2Sに新しいレコードを挿入する
using (MyDataClassesDataContext mydc = new MyDataClassesDataContext())
{
MyTable myRow = new MyTable();
mydc.MyTable.InsertOnSubmit(myRow);
mydc.SubmitChanges();
}
L2E では、これを次のように変更する必要があります。
using (MyDataClassesDataContext mydc = new MyDataClassesDataContext())
{
MyTable myRow = new MyTable(); // or = MyTable.CreateMyTable(...);
mydc.AddToMyTable(myRow);
mydc.SaveChanges();
}
変更されたオブジェクトをL2Sのデータコンテキスト/モデルに添付する
mydc.MyTable.Attach(myRow);
L2Eの場合:
// you can use either
mydc.Attach(myRow);
// or (have not tested this)
mydc.AttachTo("MyTable", myRow);
変更されたオブジェクトをL2Sのデータコンテキスト/モデルに添付する(元のオブジェクトを使用)
mydc.MyTable.Attach(myRow, myOriginalRow);
L2E(MSDN - 分離されたオブジェクトに加えられた変更を適用する):
mydc.Attach(myOriginalRow);
mydc.ApplyPropertyChanges(myOriginalRow.EntityKey.EntitySetName, myRow);
L2Sのレコードを削除する
mydc.MyTable.DeleteOnSubmit(myRow);
L2Eの場合:
mydc.DeleteObject(myRow);
L2Sでデバッグ用に作成されたSQLコマンドを表示する
mydc.Log = Console.Out;
// before mydc.SubmitChanges();
でL2EではクエリのSQLを表示できます(TFDに感謝):
using System.Data.Objects;
...
var sqlQuery = query as ObjectQuery;
var sqlTrace = sqlQuery.ToTraceString();
残念ながら、SaveChanges()の呼び出しで生成されたSQLを出力する方法は見つかりませんでした。SQLプロファイラーこのために。
存在しない場合はスキームからデータベースを作成する L2S
if (!mydc.DatabaseExists())
mydc.CreateDatabase();
L2Eの場合:
// according to TFD there are no DDL commands in L2E
L2Sのデータベースに対してSQLコマンドを実行する
mydc.ExecuteCommand("ALTER TABLE dbo.MyTable ADD CONSTRAINT DF_MyTable_ID DEFAULT (newid()) FOR MyTableID");
L2Eの場合:
EF のデータベースに対して eSQL コマンドを実行するには (注意: eSQL はまだ DDL または DML (変更、挿入、更新、削除) コマンドをサポートしていません)。
using System.Data.EntityClient;
...
EntityConnection conn = this.Connection as EntityConnection;
using (EntityCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = @"Select t.MyValue From MyEntities.MyTable As t";
var result = cmd.ExecuteReader(System.Data.CommandBehavior.SequentialAccess);
result.Read();
var myValue = result.GetValue(0);
...
conn.Close();
}
コマンド テキストは Entity SQL で記述されており、T-SQL と 100% 同じではありません。
(TFD に感謝)
同じ接続で DDL/DML コマンドが必要な場合は、データベース接続を自分で作成し、自分で作成した db 接続を使用して EF に接続し、この接続を DML コマンドに使用する必要があります。見苦しいですが、自分で確認してください。
MetadataWorkspace workspace = new MetadataWorkspace(new string[] { "res://*/" }, new Assembly[] { Assembly.GetExecutingAssembly() });
using (SqlConnection sqlConnection = new SqlConnection("Data Source=salsa;Initial Catalog=SamAlyza;Integrated Security=True"))
using (EntityConnection econ = new EntityConnection(workspace, sqlConnection))
using (AlyzaDataClassesDataContext adc = new AlyzaDataClassesDataContext(econ))
{
// now you can use the SqlConnection like always
}
新しく作成されたL2Sクラスのデフォルト値
partial void OnCreated()
{
Name = "";
}
L2E では、テーブル クラスのデフォルト コンストラクターを作成するだけです。
partial class MyTable
{
public MyTable()
{
Name = "";
}
}
CREATE TABLE dbo.[MyTable]
(
[MyTableID] uniqueidentifier NOT NULL ROWGUIDCOL CONSTRAINT [PK_MyTable] PRIMARY KEY,
[Name] nvarchar(100) NOT NULL,
) ON [PRIMARY]
ALTER TABLE dbo.[MyTable] ADD CONSTRAINT [DF_MyTable_ID] DEFAULT (newid()) FOR [MyTableID]
CREATE TABLE dbo.[MySubTable]
(
[MySubTableID] uniqueidentifier NOT NULL ROWGUIDCOL CONSTRAINT [PK_MySubTable] PRIMARY KEY,
[MyTableID] uniqueidentifier NULL,
[Subname] decimal(18,2) NOT NULL,
) ON [PRIMARY]
ALTER TABLE dbo.[MySubTable] ADD CONSTRAINT [DF_MySubTable_ID] DEFAULT (newid()) FOR [MySubTableID]
ALTER TABLE dbo.[MySubTable] ADD CONSTRAINT [FK_MySubTable_MyTable] FOREIGN KEY
(
[MyTableID]
) REFERENCES dbo.[MyTable]
(
[MyTableID]
) ON DELETE CASCADE
L2Sの対応するMySubTableを持つMyTableへのレコード
MyTable myRow = new MyTable();
myRow.MySubTable.Add(new MySubTable());
mydc.MyTable.InsertOnSubmit(myRow);
L2Eでも非常に似ています:
MyTable myRow = new MyTable();
myRow.MySubTable.Add(new MySubTable());
mydc.AddToSaLyWebsites(test);
サブテーブル内を検索する
from u in adc.MySubTable
where u.MyTableID == _searchForTableID && u.Name == _searchForName
select u
L2E では、関係列にアクセスできません。
from u in adc.MySubTable
where u.MyTable.MyTableID == _searchForTableID && u.Name == _searchForName
select u
(もちろん、使用することもできます)
from u in _searchForTable.MySubTable
where u.Name == _searchForName
select u
(奇妙な補足: これを機能させるために _searchForTable を EF にアタッチする必要はありません。)
その他メモ:
L2SではLINQのさまざまな関数を使用できます。L2Eでカスタム関数を使用するとNotSupportedExceptionが発生します。そのため、
from t in mydc.MyTable
where t.Date >= _searchForDate && t.Date <= _searchForDate.AddHours(2)
select t;
L2Eでは、
DateTime endDate = _searchForDate.AddHours(2);
from t in mydc.MyTable
where t.Date >= _searchForDate && t.Date <= endDate
select t;
(私が偶然見つけたり、誰かが回答に追加したりするたびに、この投稿にさらに多くの違いをまとめていきます)
役に立つかもしれないリンクをいくつか紹介します:
-Transact-SQL と Entity-SQL の違い
-NET - ADO.NET エンティティ フレームワークと LINQ to Entities
-Mike Taulty による Disconnected LINQ to Entities について (L2E ベータ 2 向け)
ベストアンサー1
作成されたSQLコマンドをEFでデバッグ用に表示する
using System.Data.Objects;
...
var sqlQuery = query as ObjectQuery<T>;
var sqlTrace = sqlQuery.ToTraceString();
私の知る限り、DBを作成したり、DDL作業を行うコマンドはありません。これは「Entity SQL」言語の設計上の制限です。
EDMXデザインサーフェスは現在のデータベーススキーマをマップします。その逆ではありません。