43

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 を使用してのみ機能するようです。

(この投稿では、私がそれらに出くわしたり、誰かが回答に追加したりするたびに、より多くの違いを収集します)

参考になるかもしれない いくつか
のリンク :

4

4 に答える 4

6

EFでデバッグするために作成されたSQLコマンドを表示するには

using System.Data.Objects;
...
var sqlQuery = query as ObjectQuery<T>;
var sqlTrace = sqlQuery.ToTraceString();

AFAIKには、DBを作成したり、あらゆる種類のDDL作業を実行したりするコマンドはありません。これは「エンティティSQL」言語の設計上の制限です

EDMXデザインサーフェスは、現在のデータベーススキーマをマップしますが、その逆ではありません。

于 2009-02-26T12:50:45.163 に答える
3

EF でデータベースに対して SQL コマンドを実行するには

using System.Data.EntityClient;
...
EntityConnection conn = new EntityConnection(myContext.Connection.ConnectionString);
conn.Open();
EntityCommand cmd = conn.CreateCommand();
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% は同じではありません

于 2009-03-01T04:17:33.247 に答える
1

EFの挿入から新しいID値を取得するには

Create Table dbo.MyItem (
    Id int indentity(1, 1) Primary Key,
    Value varchar(100)
)

var newItem = new MyItem() { Value = "Hello" };
context.AddToMyItem(newItem);
context.SaveChanges(true);
var theNewIdentityValue = newItem.Id;

EFの人々はこれを簡単で素晴らしい仕事にしただけです:-)

于 2009-03-01T04:34:09.043 に答える
1

L2S では、関数呼び出しのようなストアド プロシージャを使用できます。EF では、SP はエンティティを返す必要があります。これは、SP が完全なエンティティのサブセットのみを返す場合に問題を引き起こす可能性があります

于 2009-04-24T20:59:01.800 に答える