我希望标题和后面的文字清楚,我对正确的术语不是很熟悉,所以如果我发现任何错误,请更正我。我是第一次使用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);
}
}