我想为那些想要从linq2sql迁移到linq2entities和ADO.net Entity Framework(在这里称为L2E)的人们开始参考.我不想讨论哪两个更好.我只是想为那些想要从一个过渡到另一个的人创建这两者之间的差异列表.
基本的东西很简单:删除linq2sql数据类,添加ado.net模型(从数据库创建).将"实体"重命名为以前的datacontext名称.
using (MyDataClassesDataContext mydc = new MyDataClassesDataContext()) { // change data mydc.SubmitChanges(); }
在L2E中,这必须改为:
using (MyDataClassesDataContext mydc = new MyDataClassesDataContext()) { // change data mydc.SaveChanges(); }
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(); }
mydc.MyTable.Attach(myRow);
在L2E中:
// you can use either mydc.Attach(myRow); // or (have not tested this) mydc.AttachTo("MyTable", myRow);
mydc.MyTable.Attach(myRow, myOriginalRow);
在L2E中(MSDN - 对分离对象应用更改):
mydc.Attach(myOriginalRow); mydc.ApplyPropertyChanges(myOriginalRow.EntityKey.EntitySetName, myRow);
mydc.MyTable.DeleteOnSubmit(myRow);
在L2E中:
mydc.DeleteObject(myRow);
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事件探查器.
if (!mydc.DatabaseExists()) mydc.CreateDatabase();
在L2E中:
// according to TFD there are no DDL commands in L2E
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命令,则可能需要自己创建数据库连接,使用自制数据库连接连接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 }
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
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中使用miscellanous函数.如果我在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到实体
- Mike Taulty关于断开连接LINQ到实体(针对L2E的beta 2)
显示已创建的用于在EF中进行调试的SQL命令
using System.Data.Objects; ... var sqlQuery = query as ObjectQuery; var sqlTrace = sqlQuery.ToTraceString();
AFAIK没有命令来创建数据库或执行任何类型的DDL工作.这是"实体SQL"语言的设计限制
EDMX设计图面将映射您当前的数据库架构,而不是相反