如何使用数据存储库
我对存储库模式非常陌生,但到目前为止我喜欢如何使用它。我在 codeplex 上找到了这个实现。我现在的问题是:
我是否以正确的方式使用存储库模式?
和
任何人都可以为我下面的示例提供更好的解决方案吗?
这是一个示例(我是使用 poco),我在该过程的早期阶段获取了关闭延迟加载的位置。经过一些用户界面交互后,我想更新位置属性(例如名称)和相关用户(包括添加和删除):
using (var repo = RepositoryHelper.GetLocationRepository())
using (var repo2 = RepositoryHelper.GetUserRepository(repo.UnitOfWork))
{
repo.Add(location);
repo.UnitOfWork.Context.ObjectStateManager.ChangeObjectState(location, EntityState.Modified);
foreach (var user in location.Users)
{
repo2.Add(user);
if (user.Id != 0)
{
repo2.UnitOfWork.Context.ObjectStateManager.ChangeObjectState(user, EntityState.Unchanged);
}
}
foreach (var user in _remove.Where(user => user.Id != 0))
{
repo2.Delete(user);
}
repo2.UnitOfWork.Commit();
}
该示例正在运行,尽管我对如何使用 Attach 命令感到非常困惑。我认为如果对象来自另一个上下文,它就会被使用?!但如果我尝试这样做,我总是会得到一个异常,即该对象正在被另一个上下文使用。可以说,我正在分离该位置,之后我无法立即访问用户集合。
另一个问题(我认为它与此密切相关):我一直读到数据库连接应该尽可能短。因此,我将 IDisposable 接口添加到存储库中,这样我就可以像使用 ObjectContext 一样使用它们。然而我发现了一些例子(我认为也在 wpf 应用程序框架中),这不是通常的方法。那么,我应该遵循哪些词呢?
亲切的问候,
马特
i'm very new to the repository pattern, but so far i like how i can use it. I found this implementation on codeplex. My questions now are:
am i using the repository pattern in the correct manner?
and
can anyone provide a better solution for my example beneath?
Here is an example (i'm using poco) where i have fetched a location with lazyloading turned off earlier in the process. After some ui interaction i want to update the location properties (eg. name) and the related users (including add and remove):
using (var repo = RepositoryHelper.GetLocationRepository())
using (var repo2 = RepositoryHelper.GetUserRepository(repo.UnitOfWork))
{
repo.Add(location);
repo.UnitOfWork.Context.ObjectStateManager.ChangeObjectState(location, EntityState.Modified);
foreach (var user in location.Users)
{
repo2.Add(user);
if (user.Id != 0)
{
repo2.UnitOfWork.Context.ObjectStateManager.ChangeObjectState(user, EntityState.Unchanged);
}
}
foreach (var user in _remove.Where(user => user.Id != 0))
{
repo2.Delete(user);
}
repo2.UnitOfWork.Commit();
}
The example is working, although i'm very confused about how to the the Attach command. I thought it is used if the object comes from another context?! But if i try that, i always get an exception, that the object is in use by another context. And lets say, i'm detaching the location, i cannot access the Users collection right after that.
Another question (and i think it's closly related to this): i've always read, that the database connection should be as short as possible. Therefor i added the IDisposable interface to the repositories, so i can use them in the same way as an ObjectContext. However i found some examples (i think also in the wpf application framework), where this is not the usual approach. So, what words should i follow?
Kind Regards,
matt
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
关键问题:为什么要使用存储库和工作单元 (UoW) 模式?
人们通常使用这些模式将 EF 代码分离到内部存储库和 UoW 实现。因此,上层将完全独立于 EF。
您的实现不提供这种分离。它只是
ObjectContext
和ObjectSet
的一个奇怪的包装。在这种情况下,您根本不需要存储库和 UoW,可以直接使用 EF 类。即使使用 EF 类,您仍然可以使代码可测试(人们有时引入存储库和 UoW 的另一个错误原因)。对于你的第二个问题。
ObjectContext
的生命周期应尽可能短,但这并不意味着您应该为每个查询创建新的上下文。ObjectContext
在内部处理连接,并且仅在需要时才打开它。之所以应该在短时间内使用 ObjectContext 是因为它还实现了 UoW 模式以及 IdentityMap 模式(我描述了含义 此处)。在 WPF 应用程序中,ObjectContext
通常与呈现要修改的数据的窗口或控件一起存在。The key question: Why do you want to use repository and unit of work (UoW) patterns?
People usually use these patterns to separate EF code to internal repository and UoW implementation. Because of that upper layers will be completely independent on EF.
Your implementation doesn't provide this separation. It is just a strange wrapper around
ObjectContext
andObjectSet
. In such case you don't need repository and UoW at all and you can use EF classes directly. Even with EF classes you can still make your code testable (another wrong reason why people sometimes introduce repositories and UoW).To your second question. Lifetime of
ObjectContext
should be short as possible but it doesn't mean that you should create new context for each query.ObjectContext
handles connection internally and it opens it only when it is needed. The reason why ObjectContext should be used for short period of time is because it also implements UoW pattern and moreover IdentityMap patterns (I described implications here). In WPF applicationObjectContext
usually lives as long as the window or control presenting data for modification.