Chr*_*rds 9 .net vb.net linq-to-sql
众所周知,如果已经加载了实体,则无法直接在Linq to SQL中设置外键ID.但是,您可以通过它的外键查找实体,然后使用实体关系将实体设置为外部实体.(为了简单起见,我在这里取出了枚举并使用了整数值).即如果我有一个加载的约会实体和一个相关的AppoinmentStatus实体,我不能这样做: -
ExistingAppointment.AppointmentStatusID = 7
Run Code Online (Sandbox Code Playgroud)
但我可以这样做: -
ExistingAppointment.AppointmentStatus = (From appstat In db.AppointmentStatus _
Where appstat.StatusID = 7 _
Select appstat).Single
Run Code Online (Sandbox Code Playgroud)
我有这样的事情乱丢我的代码,我想重构.所以...
我显然可以在这样的模块中使用辅助方法: -
Module Helper
Public Shared Function GetAppointmentStatus(ByVal AppStatusID As Integer) As AppointmentStatus
GetAppointmentStatus = (From appstat In db.AppointmentStatus _
Where appstat.AppointmentStatusID = AppStatus _
Select appstat).Single
End Function
End Module
Run Code Online (Sandbox Code Playgroud)
我甚至可以把它变成一个扩展方法,就像这样.
Imports System.Runtime.CompilerServices
Module Helper
Extension()> _
Public Shared Function GetAppointmentStatus(ByVal db as DataClassesDataContext, ByVal AppStatusID As Integer) As AppointmentStatus
GetAppointmentStatus = (From appstat In db.AppointmentStatus _
Where appstat.AppointmentStatusID = AppStatusID _
Select appstat).Single
End Function
End Module
Run Code Online (Sandbox Code Playgroud)
我也可以将它放在Linq to SQL分部类中,就像这样.
Partial Public Class DataClassesDataContext
Public Function GetAppointmentStatus(ByVal AppStatusID As Integer) As AppointmentStatus
GetAppointmentStatus = (From appstat In Me.AppointmentStatus _
Where appstat.AppointmentStatusID = AppStatusID _
Select appstat).Single
End Function
End Class
Run Code Online (Sandbox Code Playgroud)
此外,我可以将代码放在Linq to SQL Appointment Entity分部类中,如下所示: -
Partial Public Class Appointment
Public Function GetAppointmentStatus(ByVal db as DataClassesDataContext, ByVal AppStatusID As Integer) As AppointmentStatus
GetAppointmentStatus = (From appstat In db.AppointmentStatus _
Where appstat.AppointmentStatusID = AppStatusID _
Select appstat).Single
End Function
End Class
Run Code Online (Sandbox Code Playgroud)
我应该做什么以及为什么,或者有更好的选择吗?
对此有两种主要的思想流派:
将逻辑放入DataContext(部分类,如果您DataContext手动编码,则为实际类)。其背后的基本原理是,您DataContext已经了解所有不同的实体,因此这不会创建任何额外的耦合,也不会导致类膨胀。
当然,缺点是,如果您有几百个这样的 API 方法(您最终可能会这样做),那么您DataContext很快就会开始变成一团泥球,里面充满了任何程序员决定扔进去的每个随机查询 API .您可以尝试通过将相关函数分离到同一部分类的不同实例中来清理这个问题DataContext,但这实际上只是一个表面上的改进。
将逻辑放入存储库类中,即AppointmentRepository. 这种方法的两个优点是(a)能够在存储库和 IoC 框架上使用依赖项注入,以防您决定更改数据模型,以及(b)您坚持单一职责原则-该方法所在的位置实际上是有意义的。
将它们放入存储库的主要缺点是: (a) 它们可能会复制DataContext存储过程中已经存在的非常相似的逻辑;(b) 当涉及到事务管理时,它们有一种令人头痛的方式(如果你也使用它们来保存);(c) 当您开始有大量自定义查询,这些查询返回针对特定操作或报告专门定制的 DTO 时,您只剩下两个糟糕的选择:为每个 DTO 创建一个存储库,或者创建一个主数据库所有 DTO 或其中一些松散相关组的“实用程序”存储库。两者最终都是一个相当糟糕的设计。
这些就是权衡;只有您可以决定哪个更适合您自己的目的。
我绝对建议不要使用扩展方法,因为扩展方法很难发现(您不能只键入方法并让 Intellisense 获取相关参考),而且当您有能力时,它们也根本没有必要直接修改或扩展(通过部分)原始类。
我还建议不要延长Appointment课程时间;我们使用 Linq To SQL 等工具的原因之一是我们可以处理 POCO 实体,而无需了解它们的来源。出于这个原因,我个人非常反对将实体类与其耦合DataContext——依赖关系应该只是单向的。