Tim*_*sen 61 .net comparison orm
我正和某人谈论实体框架,我还没有真正参与其中,但我想学习它.但是,我是否应该学习它仍然有点困惑.我听说很多人说你不应该使用实体框架,但我没有听到任何争论为什么会这样.
所以我的问题是,与其他产品相比,使用实体框架的专业和利益是什么.喜欢
在易用性,可测试性,语义方面......
我知道有一些重复的 问题.但他们都有点过时(2008,2009),说实话,这些论点也缺乏一些东西.我知道实体框架4.0可用,但我还没有找到一个好的(完整的)比较.
这里的一些好人通过解释不同框架的一些细节来回答我的问题.认为将它们展示在这里以供将来参考可能会很好.
Die*_*hon 52
由于J. Tihon在解释EF功能方面表现出色,我只列出了NHibernate在EF周围运行的区域:
我认为可扩展性是主要的卖点.NH的每个方面都可以正确地与其他方面分离,使用您可以随时扩展的接口和基本绑定,并在配置选项中公开.
EF遵循默认情况下关闭事件的常用MS模式,我们将在后面看到可扩展的内容.
J. *_*hon 34
我花费了大量时间来根据我的需要改变实体框架,因此可以说它满足了ORM所需的大部分要求.但是有些方面太复杂了,因为其他ORM已经表明它可以变得更容易.
例如,开始使用Entity Framework非常简单,因为您可以在Visual Studio中启动Designer并在几分钟内完成一个有效的ORM.但是最终会得到与设计者创建的ObjectContext相关联的Entity-Classes(使用自定义T4模板可以避免这种情况).这不是一件坏事,但它就是那种微软的"入门"方法,你不想在真正的应用程序中使用它.
但是如果您深入了解实体框架,您可以看到,如何避免大部分陷阱:Designer生成EDMX文件,(如果您在XML编辑器中查看)只不过是三者的组合ORM的主要方面,物理存储(您的数据库),概念模型(您的实体类)以及它们之间的映射.应用于Visual Studio中的.edmx文件的自定义构建操作会将这3个部分拆分为三个单独的文件,并将它们作为嵌入资源添加到程序集中.在创建ObjectContext时,ConnectionString中使用了这三个文件的路径(这对我来说总是有点混乱).你在这里真正可以做的是自己做这一切.这意味着在XML编辑器(很像NHibernate)中编写存储架构,概念模型和映射,并将它们嵌入到包含模型的程序集中.
基本的Entity Framework基类"ObjectContext"可以从这三个文件构建(它需要MetadataWorkspace和EntityConnection),但重点是,您可以完全控制ObjectContext的创建方式.这为您可能无法从实体框架中获得的许多功能打开了大门.例如:您可以在同一个程序集中嵌入多个SSDL存储架构以匹配特定的数据库类型(我通常为SQL Server添加一个,为SQL Server CE 4.0添加一个).并创建一个构造函数重载,为特定类型的DbConnection选择适当的存储架构.
由于您现在拥有自己的ObjectContext实现,因此可以在其上实现各种接口.就像你自己的IRepository,但因为我喜欢ObjectContext方法,我创建了类似的东西:
interface ICatalog
{
IEntitySet<Article> { get; }
void Save();
}
interface IEntitySet<T> : IQueryable<T>
{
void Add(T);
void Remove(T);
}
class EntityFrameworkCatalog : ICatalog
{
...
}
Run Code Online (Sandbox Code Playgroud)
但是如果你有一个Entity Framework ObjectContext,那么创建一个Repository非常简单,而且你可以获得一个IQueryable.根据这些信息,您可以避免在服务和ORM之间建立强大的类耦合,并在测试中完全模拟实体框架.此外,在测试实体框架实现时,您可以在单元测试期间使用SQL Server CE数据库以确保您的映射正常(通常CE的存储架构和完整的SQL Server之间的差异只是一些数据 - 类型).因此,您可以实际测试实体框架实现的所有行为.
这使得Entity Framework很好地适应了现代软件概念,但它并没有对您强制执行此类实践,这使得"入门"变得更加容易.
现在到复杂的位:实体框架有一小组受支持的CLR类型,它们基本上只包括原始类型,如整数,字符串和字节数组.它还提供了一定程度的复杂类型,遵循相同的规则.但是,如果您有一个复杂的实体属性,例如文档的DOM表示,您希望在数据库中将其序列化为XML,那该怎么办呢?据我所知,NHibernate提供了一个名为IUserType的功能,它允许您为您定义这样的映射.在实体框架中,这变得更加复杂,但它仍然以自己的方式存在.概念模型允许您包含程序集内部复杂类型(只要您告诉ObjectContext它(ObjectContext.CreateProxyTypes(Type [])).因此您可以为原始类型创建一个包装器,只有实体框架如下:
class Document : IXmlSerializable { }
class Article
{
public virtual Document Content { get; set; }
}
internal class EntityFrameworkDocument : Document
{
public string Xml
{
get
{
// Use XmlSerializer to generate the XML-string for this instance.
}
set
{
// Use XmlSerializer to read the XML-string for this instance.
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在EF可以从存储中返回那些序列化文档,将它们写入它,要求您拦截文章的存储并用EntityFrameworkDocument替换一个简单的Document,以确保EF可以序列化它.我相信其他ORM很容易做到这一点而且情况会变得更糟.目前没有办法,使用System.Uri类(它是不可变的,但否则可以工作)或Enum.除了这些限制,您还可以满足大多数需求.但你会花很多时间(就像我一样).
由于我对其他ORM的经验有限,我总结一下:
它只需要System.Data和System.Data.Entity,你甚至可以为通常需要引用的其他提供者包含多个存储模式,但是如果你坚持使用DbConnection,你可以这样做:
ICatalog Create(DbConnection connection, string storageSchemaPath)
ICatalog CreateMySql(DbConnection mySqlConnection)
{
return Create(connection, "res://Assembly/Path.To.Embedded.MySql.Storage.ssdl");
}
编辑
我最近发现,如果您的实体和"目录"实现在同一个程序集中,则可以使用内部属性进行XML序列化过程.因此,与其获得的内部EntityFrameworkDocument从Document您可以添加所谓的内部属性Xml的Document类本身.这仍然只适用于您完全控制您的实体,但它不需要拦截对目录的任何更改,以确保使用您的派生类.CSDL看起来一样,EF只允许映射的属性是内部的.我仍然必须确保这在中等信任环境中有效.
当我们迟早从头开始使用ADO.NET时,我们会感到沮丧并开始寻找其他解决方案.我测试过很多.大多数ORM框架都有很多功能,需要大量的知识.有些看起来很容易(例如:EF,Castle ActiveRecord),但有很多事情你应该关心:
如果您是一位经验丰富的开发人员,并且您已准备好应对所有这些陷阱和事情,那么我问您:您的同事也是吗?
有更简单的方法来编写ADO.NET,而不是松散地控制正在发生的事情.看看PainlessDAL.
"优雅"编码并不总是最好的方式.
| 归档时间: |
|
| 查看次数: |
30973 次 |
| 最近记录: |