差异

0

当实现使用小巧玲珑的ORM库模式,我目前做如下:差异

private readonly ConnectionStrings _connectionStrings; 
private IDbConnection _db; 

public CustomerRepository(IOptions<ConnectionStrings> connectionStrings) 
{ 
    _connectionStrings = connectionStrings.Value; 
    _db = new SqlConnection(_connectionStrings.DefaultConnection); 
} 

public Customer Find(int id) 
{ 
    return this._db.Query<Customer>("SELECT * FROM Contacts WHERE Id = @Id", new { id }).SingleOrDefault(); 
} 

可有人请告诉我是否应该这样做,或者如果我应该在每个存储库函数中使用带有新SqlConnection的using语句。

我假设我的上面的代码需要类似UnitOfWork的东西才能生效吗?而且在完成运行所有需要的存储库功能时,也可以采用某种方式处理连接。

+3

在每种方法中使用'using'语句。不要重用连接或任何ADO.NET对象。 [相关](http://stackoverflow.com/questions/9705637/executereader-requires-an-open-and-available-connection-the-connections-curren/9707060#9707060) –

+1

使用'using'语句。 – stuartd

+0

感谢球员,但你能解释为什么我看到一些例子,如何时使用EF,通过依赖注入传入上下文,然后使用?还有可能通过几个使用语句来实现UnitOfWork?我正在考虑使用以下方法:https://github.com/timschreiber/DapperUnitOfWork –

回答

1

推荐的方法是使用using语句。用户paulwhit解释他们的使用大有this答案:

的原因“使用”的声明是要确保,因为它超出范围的对象,一旦配置,并且它不需要明确的代码确保发生这种情况。

在你的方法using语句和具有连接是一个类成员之间的本质区别在于,using声明可以确保一旦你与你的操作完成,并已退出该块,您的连接关闭并妥善处理。这消除了开发人员可能出现的任何错误,并且通常使得所有的事情都更加简洁。

在这种情况下,using声明的一个重要的额外好处是它可以确保连接被处置,即使存在异常(尽管值得注意的是,这不是严格意义上的唯一方法) 。根据documentation

using语句确保即使在对象上调用方法时发生异常,也会调用Dispose。

如果您想让连接成为类成员,那么导致您的程序早退出的方法中间的未处理异常可能会使连接处于打开状态。这当然不是一件好事。

所以总结一下,除非你有一个很好的理由不去,那就去using声明吧。

1

通常,当一个类型实现IDisposable(并且因此与using作品)可以有时是包装在另一种类型的有用的,其具有其它类型也实现IDisposable和具有其Dispose()呼叫被包装的对象,并然后使用using(或其他机制调用Dispose())。

问题是这是否是有时是之一。

不是。特别需要注意的是,SqlConnection在后台实现了池化,因此(除非您明确选择退出连接字符串)而不是Dispose()关闭到服务器的整个连接实际上发生的是组件内部的一个对象,该对象处理内存为SqlConnection下一次打开具有相同连接字符串的SqlConnection时,将连接的详细信息放入池中以再次使用。

这意味着您的应用程序将通过SqlConnection类的许多用途尽可能少地使用连接。但是,你要阻止通过尽可能不返回游泳池的方式保持游泳池外的连接。

+0

因此,您似乎在说:每个函数的使用语句并不是那么糟糕。如果我需要在交易中批量处理多个报表,该怎么办?是否可以在存储库或多个存储库中调用3个独立的函数,并让它们全部在事务中运行?似乎每个函数都有一个using语句会很困难。 –

+1

不,我要进一步说每个函数的使用语句都很棒!虽然交易是一个不同的问题,但我不得不承认,我并不关心池化机制是否是事务感知的,因此它是否仍能正常工作。 –