linq2sql から linq2entities と ADO.net Entity Framework (ここでは L2E と呼ばれます) に移行したい人のためのリファレンスを開始したいと思います。この二つのどちらが優れているか議論したくありません。あるものから別のものに移行したい人のために、これら 2 つの違いのリストを作成したいだけです。
基本的なことは簡単です。linq2sql データ クラスを削除し、ado.net モデル (データベースから作成) を追加します。「エンティティ」の名前を以前のデータコンテキストの名前に変更します。
さて、違い。たとえば、L2S で変更を永続化 (保存) するには、次を使用します。
using (MyDataClassesDataContext mydc = new MyDataClassesDataContext())
{
// change data
mydc.SubmitChanges();
}
L2E では、これを次のように変更する必要があります。
using (MyDataClassesDataContext mydc = new MyDataClassesDataContext())
{
// change data
mydc.SaveChanges();
}
2 番目の例では、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();
}
他のコード スニペットについては、using (...) 部分と SubmitChanges/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 (alter、Insert、update、delete) コマンドをまだサポートしていないことに注意してください):
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 クラスのデフォルト値を提供するには、部分メソッド OnCreated をオーバーライドします。
partial void OnCreated()
{
Name = "";
}
L2E では、テーブル クラスのデフォルト コンストラクタを作成するだけです。
partial class MyTable
{
public MyTable()
{
Name = "";
}
}
次の例は、2 つのテーブル間の 1:n 関係に関するものです。ここでは SQL でテーブルを定義しているので、私が何について書いているかがわかります。
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);
L2Sで subtable を検索するには、次を使用できます。
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;
L2S はデータベースから自動生成された ID などの自動生成された値を読み取ることができますが、L2E ではこれは SQL 型 ID を使用してのみ機能するようです。
(この投稿では、私がそれらに出くわしたり、誰かが回答に追加したりするたびに、より多くの違いを収集します)