建议对LINQ到SQL映射对象设计
-
21-09-2019 - |
题
我希望标题和下面的文字是明确的,我不是很熟悉,正确的条款,以便请纠正我,如果我得到任何错误。我使用LINQ的ORM的第一次,我想知道如何解决以下。
说我有两个DB表:
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 comsumers应该并不需要编写自己的LINQ查询得到的数据,所以我应该某处包装在一个功能或属性此查询。
所以现在的问题是,在这个例子中,你会一个电话属性添加到IUSER或不?
在换句话说,应该我的接口具体可以建模我的数据库对象(在这种情况下,手机不属于IUSER),或者是它们实际上简单地提供一组其概念上与一个用户相关联的功能和性能(在这种情况下,它)?
似乎有缺点,这两种观点,但我不知道是否有解决问题的标准方法。或者只是智慧的任何一般的话,你可以分享。
我首先想到的是使用扩展方法,但实际上并不在这种情况下工作。
解决方案
我已经有一些可怕的经验,努力背后的接口抽象LINQtoSQL实体。这是前一段时间,但是从内存中的主要问题是,它完全打破协会。举例来说,如果你有一个Customer
- > Order
关系,你最终会露出它作为ICustomer
,与IOrder
s的集合,这意味着Customer
必须做一些尴尬映射投它Order
对象作为IOrder
s的内部集合<。 / p>
然后你必须假定,当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);
}
}
其他提示
您接口应该模型,你会如何喜欢使用的对象。既然你正试图抽象,那么消费者应该不必查询数据库。无论你把它的属性,或一个单独的函数调用(即GetPhones()),这完全取决于你。既然你是完全包裹的东西,你就必须做出有多深/懒洋洋地要载你的对象一些选择。
您应该电话属性添加到IUSER并使其可为空,所以用户没有电话谁也,这将是空的。
既然你不希望API的消费者编写查询,比你应该实现的功能类似的getUser()...等。
下面是在Asp.net
文章ABT n层应用的一个很好的列表我倾向于考虑LINQ2SQL相关的东西是数据访问代码的实现细节,并且像数据库的真实结构,不一定要暴露于所述系统的其他部分。
如果您的API是要被其他人食用它应该是协调的和易于使用的,而不是由事物的消费者并不需要了解混乱。如果我处理用户和他们的电话时,我真的不想知道DataContexts或(啊)数据集。
此外,通过保持大量代码昧L2S和数据库的你将有一个更简单的时间测试,进行模式更改(哦,所以现在的用户表需要不断作出的每个改变的历史),甚至会改变的ORM完全。