Linq 2 SQL から Linq 2 エンティティに移行するにはどうすればいいですか? 質問する

Linq 2 SQL から Linq 2 エンティティに移行するにはどうすればいいですか? 質問する

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デザインサーフェスは現在のデータベーススキーマをマップします。その逆ではありません。

おすすめ記事