关于 Linq 到 SQL 映射对象设计的建议
Posted
技术标签:
【中文标题】关于 Linq 到 SQL 映射对象设计的建议【英文标题】:Advice on Linq to SQL mapping object design 【发布时间】:2010-03-19 12:19:47 【问题描述】:我希望标题和以下文字清楚,我对正确的术语不是很熟悉,所以如果我有任何错误,请纠正我。我是第一次使用 Linq ORM,想知道如何解决以下问题。
假设我有两个数据库表:
User
----
Id
Name
Phone
-----
Id
UserId
Model
Linq 代码生成器生成一堆实体类。
然后我编写自己的类和接口来包装这些 Linq 类:
class DatabaseUser : IUser
public DatabaseUser(User user)
_user = user;
public Guid Id
get return _user.Id;
... etc
到目前为止一切顺利。
现在很容易从Phones.Where(p => p.User = user)
找到用户电话,但 API 的用户肯定不需要编写自己的 Linq 查询来获取数据,所以我应该将此查询包装在某个函数或属性中.
所以问题是,在本例中,您是否会向 IUser 添加 Phones 属性?
换句话说,我的界面是否应该专门为我的数据库对象建模(在这种情况下,电话不属于 IUser),或者它们实际上只是提供一组在概念上与用户相关联的函数和属性(在它在哪种情况下)?
这两种观点似乎都有缺点,但我想知道是否有解决问题的标准方法。或者只是您可以分享的任何一般的智慧之言。
我的第一个想法是使用扩展方法,但实际上在这种情况下不起作用。
【问题讨论】:
【参考方案1】:我在尝试将 LINQtoSQL 实体抽象到接口后面时有过一些糟糕的经历。那是不久前的事了,但从记忆中,主要问题是它完全打破了联想。例如,如果你有一个Customer
-> Order
关系,你最终将它暴露为一个ICustomer
,并带有IOrder
s 的集合,这意味着Customer
必须做一些尴尬的映射到将其内部的 Order
对象集合转换为 IOrder
s。
然后你必须假设当IOrder
被传回时,我们可以将它转换为Order
。否则 LINQtoSQL 无法处理它,但这首先破坏了在那里拥有接口的意义。
我强烈建议您不要尝试过多地抽象出实体类,LINQtoSQL 实际上并没有给它们带来任何真正的魔力,DataContext 处理它们的持久性生命周期,因此它们仍然是可测试的。
我希望隐藏在接口后面的方面是与 DataContext 的交互,例如使用 Repository 样式的类:
public interface IPhoneRepository
IEnumerable<Phone> GetPhonesForUser(User user);
public class L2SPhoneRepository : IPhoneRepository
private readonly MyDataContext context;
public L2SPhoneRepository(MyDataContext context)
this.context = context;
public IEnumerable<Phone> GetPhonesForUser(User user)
return context.Phones.Where(p => p.User == user);
【讨论】:
我想我可以期待 Apple 的律师通过IPhoneRepository
来信【参考方案2】:
您的界面应该模拟您希望如何使用对象。由于您正在尝试抽象,因此消费者不必查询数据库。是否将其设为属性或单独的函数调用(即 GetPhones())完全取决于您。由于您正在完全包装事物,因此您必须对要加载对象的深度/延迟做出一些选择。
【讨论】:
【参考方案3】:您应该将 Phones 属性添加到 IUser 并使其可为空,因此对于没有 Phone 的用户,它将为空。
由于您不希望 API 的使用者编写查询,因此您应该实现 GetUser().. 等函数。
这是一个很好的文章列表,在 Asp.net 中使用 abt n-tier 应用程序
http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=416
【讨论】:
【参考方案4】:我倾向于将 Linq2Sql 相关的东西视为数据访问代码的实现细节,并且与数据库的真实结构一样,不一定要暴露给系统的其他部分。
如果您的 API 将被其他人使用,那么它应该具有凝聚力且易于使用,并且不会被消费者不需要知道的事情所困扰。如果我正在与用户和他们的手机打交道,我真的不想了解 DataContexts 或(呃)DataSets。
此外,通过保持大部分代码对 L2S 和数据库一无所知,您将可以更轻松地进行测试、进行架构更改(哦,所以现在用户表需要保留每次更改的历史记录)甚至更改完全是 ORM。
【讨论】:
以上是关于关于 Linq 到 SQL 映射对象设计的建议的主要内容,如果未能解决你的问题,请参考以下文章
从 Money 到 Double 的 LINQ 到 SQL 映射