2012-10-01 53 views
8

我正处于建立新开发项目的早期阶段,我不确定如何设置我的数据库访问策略。我将使用Visual Studio 2012,并将以.NET 4.5和SQL Server 2008或2012为目标。实体框架,Dapper和SSDT的组合?

我不确定是否使用实体框架,如果是,使用实体框架。由于从数据库中读取数据然后处理它将成为此应用程序的主要工作,查询性能将变得非常重要。我知道EF5在这方面比EF4.x好很多,但这并不是我最担心的固有的EF开销(尽管Dapper至少有两倍的速度),但更多的是它为你提供的懒惰作为开发人员,因为通过LINQ查询太多太容易了。所以我希望纯SQL查询成为获取数据的主要方式。

不过,我会最怀念EF是:

  1. 编译时查询检查。
  2. 更改跟踪。
  3. 第一次开发代码。
  4. 工作模式的单位。

我可以在没有变更追踪的情况下生活,通常不难确定新增或更新的内容。

我所希望的是,这个项目的开发人员不必乱用表格设计师,但他们可以简单地编写POCO。所以为此,我非常欣赏EF的代码优先方法。有了这个,开发人员可以克隆源代码,请致电update-database并拥有一个可工作的本地数据库。这在过去对我来说非常合适。

另一件对我来说非常重要的事情是一个工作模式单元,或插入和更新的原子性。我想排队所有更改,并有一个点,我拨打SaveChanges。使用像DapperExtensions这样的库,您会得到一个Insert方法,但它会立即执行数据库调用。你可以通过在它周围包装一个事务来使它成为原子,但这与排队它不一样。所以我必须为此自行推出某种排队机制。

对于编译时查询检查,我考虑使用SQL Server数据工具(SSDT)。查询将是存储过程(以避免C#代码中的大型查询字符串blob)以及使用SSDT,这些可以在构建时检查。 SSDT的另一个优点是可以将存储过程从Visual Studio部署到目标数据库。最重要的是,这些SQL脚本将存在于源代码管理中。

因此,既然,我的解决方案将基本上由三个数据访问技术:

实体框架

  • 将负责创建从POCO datamodels数据库。
  • 将用于通过其工作模式插入/更新数据。需要注意的是,您首先必须将通过SQL获取的实体Attach添加到上下文中。

SSDT

  • 将用于在编译时间来验证SQL脚本。
  • 允许脚本存在于Git中。
  • 将部署EF无法部署到您的数据库的东西。

小巧玲珑/其他微型ORM

  • 将用于获取数据

我不禁觉得这是一个有点怪人解决方案,我用各种的一切的零碎。我还不确定SSDT和EF会以一种很好的方式一起工作。这个快速的例子似乎工作正常,但:

// Combo of Dapper, EF and a stored proc that was published through SSDT 
static void Main(string[] args) 
{ 
    var connectionString = ConfigurationManager 
    .ConnectionStrings["DbDataContext"].ConnectionString; 

    using (var conn = new SqlConnection(connectionString)) 
    using (var ctx = new DbDataContext()) 
    { 
    conn.Open(); 

    var product = conn.Query<Product>("GetProduct", 
     commandType: CommandType.StoredProcedure).First(); 

    ctx.Products.Attach(product); 

    var order = new Order 
    { 
     Product = product 
    }; 

    ctx.Orders.Add(order); 

    ctx.SaveChanges(); 

    } 
} 

这种方法似乎可以工作,但它也很混乱。但是如果我放弃SSDT,我会错过SQL的编译时检查,如果我放弃实体框架,我会错过代码优先和更容易的插入,如果我放弃直接SQL,我会错过大量的表现。

是否有替代品可以忽略?如果不是,这里最好的办法是什么?

+0

“作为开发者提供的懒惰” - 这是你的工作,不要懒惰; EF提供完美的性能工程。 – millimoose

+1

是的,但不使用LINQ。你必须下到原始的SQL,然后它仍然只有普通ADO.NET/Dapper(http://goo.gl/ctD9f)的一半。不妨跟Dapper一起去查询。然而,我想避免在C#代码中查询大字符串的匿名blob,这就是为什么我查看SSDT将其移出代码的原因。 – JulianR

+0

好的,但这是开发人员控制之外的框架开销问题。我的观点仅仅是“提供懒惰”不是选择或不选择技术的好理由。如果您愿意为ORM“深度”交换开销,您仍然可以选择避免由N + 1选择问题导致的性能问题。 (这个问题对性能的影响也很大,在原始SQL中也很容易遇到,而且解决起来更具挑战性,因为在SQL中编写大量的uberqueries比LINQ更困难。) – millimoose

回答

3

你应该确实检查出ServiceStack.Orm。

https://github.com/ServiceStack/ServiceStack.OrmLite

它的特点一吨,使用TT文件,包括模型根,它可以创建数据库表,以及。

而且它支持LINQ。

它的疯狂闪电很快。

+32

好极了,现在他有四件事可供选择。 –

+0

我考虑过了,但是“复杂的类型在文本字段中出现了斑点”,这让我不得不说。甚至与我无关,只是......很奇怪。更多属于非结构化文档NoSQL数据存储的内容。它可以从POCO创建表格很好,但它无法进行迁移。没关系,因为SSDT可以,但我不认为它比Dapper或PetaPoco更有优势。 – JulianR

+0

hmm标量/内置类型在OrmLite中与预期保持一致 - 只有复杂类型属性被透明地堵塞,如果其他Micro ORM没有这样做,那么我假设它们不支持具有复杂类型属性的POCO(它更好有什么工作是正确的?)。 OrmLite还提供了一种类型化的API,可用于所有主要支持的RDBMS。 – mythz