关于 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,并带有IOrders 的集合,这意味着Customer 必须做一些尴尬的映射到将其内部的 Order 对象集合转换为 IOrders。

然后你必须假设当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 映射对象设计的建议的主要内容,如果未能解决你的问题,请参考以下文章

Linq-to-sql 不产生多个外连接?

从 Money 到 Double 的 LINQ 到 SQL 映射

mybatis关于ORM的使用以及设计[DaoInterface 转换 Mapper代理对象]

关于C#3.5用LINQ映射问题!

LinQ to SQL 查询

mybatis关于ORM的使用以及设计[参数对象转换为SQL语言]