我希望标题和后面的文字清楚,我对正确的术语不是很熟悉,所以如果我发现任何错误,请更正我。我是第一次使用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查询来获取数据,因此我应该将此查询包装在某个函数或属性中。

因此,问题是,在此示例中,您是否将Phones属性添加到IUser?

换句话说,我的界面应该专门为数据库对象建模(在这种情况下,电话不属于IUser),或者它们实际上只是提供一组在概念上与用户相关联的功能和属性(在这种情况下,它是)吗?

两种观点似乎都有弊端,但我想知道是否存在解决此问题的标准方法。或者,您可以分享任何一般性的智慧之词。

我的第一个想法是使用扩展方法,但实际上在这种情况下不起作用。

最佳答案

我有一些糟糕的经验,试图在接口后面抽象LINQtoSQL实体。不久前,但是从记忆中看,主要问题是它完全破坏了关联。例如,如果您具有Customer-> Order关系,则最终将其作为ICustomer公开,并带有IOrder的集合,这意味着Customer必须进行一些尴尬的映射才能将其内部Order对象集合转换为IOrder

然后,您必须假设,当IOrder返回时,我们可以将其强制转换为Order。否则LINQtoSQL无法对其进行处理,但是这首先挫败了在该处拥有接口的意义。

我强烈建议您不要尝试过多地抽象实体类,LINQtoSQL实际上不会在其中添加任何真正的魔力,DataContext处理其持久性生命周期,因此它们仍可测试。

我希望隐藏在接口后面的方面是与DataContext的交互,例如使用存储库样式的类:

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);
    }
}

08-28 07:24