在使用LINQ to SQL时,如何抽象出持久性代码?

时间:2009-05-17 18:14:52

标签: .net linq-to-sql

我喜欢LINQ to SQL,但是在使用它时,我的存储库代码由LINQ to SQL框架生成,因此与SQL Server数据库紧密耦合。

您是否有人以抽象的,松散耦合的方式使用LINQ to SQL?如果是这样,您是如何解决保持代码数据库无关的问题的?

4 个答案:

答案 0 :(得分:3)

对我自己;我满足于重用LINQ / dbml生成的对象模型,因为实际上属性不会伤害我,任何其他实现都可以提供类似的模型 - 但我不使用我的数据上下文在DAL之外。所以我有类似的东西:

  • IFooRepository - 使用生成的dbml对象和一些POCO模型类定义可用的方法
  • FooRepository - 了解数据上下文的实现

我的存储库方法不会公开IQueryable<T>Expression<...>等LINQ概念,因为它们是leaky abstractions;其他实现将以不同的方式工作(例如,EF支持两者的不同方面)。

此外 - 我已经将大多数关联属性标记为内部属性,并且仅在DAL查询期间使用它们(在OO工作期间没有那么多)。

我可以映射到纯POCO,但我没有看到好处。我在这里有更多的想法:Pragmatic LINQ

答案 1 :(得分:1)

您可以使用类似NerdsDinner中使用的方法。该项目使用dat作为数据库的网关,并在其周围构建一个存储库。

这种存储库模式根据被调用的方法添加了一些条件,过滤器,排序命令等,然后将IQuerable返回给调用者,让门打开以进行进一步修改。

实际上,在围绕NHibernate ISession构建存储库时,您的工作方式几乎相同。

例如,如果您决定用NHibernate替换LinqtoSql,您只需查询存储库中的Linq会话而不是datacontext。当然,您需要使用LinqtoSql自动添加的属性来完成部分类。

答案 2 :(得分:0)

嘿nathan,好问题。

正如其他人所说,最好的办法是抽象所有的GET / WRITE方法,并将DataContext完全隐藏在业务逻辑中。

我的方法是用一堆通用方法编写DAL,这些方法使用反射来做任何必要的事情。

在这些情况下,一旦方法收到一个对象,比如“产品”,它就可以在内部做任何想做的事情,而不管你的ORM /数据访问技术。如果你想要,它可以简单地根据一些参数和对象的反射来编写一个SQL字符串。

HOWEVER ,单独执行此操作不会完全解除LINQ to SQL的错误。

问题实际上是实体本身。即使您抽象出检索数据的方法,您仍然会在业务​​逻辑中一直使用这些Entites。

我觉得,此刻,这只是我准备好的事情,因为重新编写我自己的断开连接的实体似乎是一座我不准备跨越的桥梁,只是因为它似乎很多不必要的工作......

我很想知道其他人如何解决这个问题。

喝彩!

答案 3 :(得分:-1)

上面的Mouk提到了NerdsDinner中的存储库模式,还有一个如何快速设置它的教程:

http://www.asp.net/learn/mvc/tutorial-10-cs.aspx

这是在NerdsDinner之前发布的一系列很好的教程。这里的概念也可以在传统的asp.net Web表单应用程序中设置。

另外,我建议使用Linq To Entities(更新,以及对其他数据库的更多支持),其中一些基础知识在这里: http://www.asp.net/learn/mvc/tutorial-16-cs.aspx