2010-04-15 53 views
2
class UserDatastore : IUserDatastore 
{ 
    ... 

    public IUser this[Guid userId] 
    { 
     get 
     { 
      User user = (from u in _dataContext.Users 
          where u.Id == userId 
          select u).FirstOrDefault(); 

      return user; 
     } 
    } 

    ... 
} 

一个在我们的团队开发人员争辩说,在上述情况下的索引是不恰当的,并且一个GetUser(Guid id)方法应优先。使用索引从数据存储检索的LINQ to SQL对象

的论据在于:

1)我们不是索引到内存中的集合,索引基本上是执行一个隐藏的SQL查询 2)在索引使用GUID是坏的(标记的FxCop这也) 3)从分度器返回null不正常行为 4)的API用户通常不希望任何的这种行为

我同意的程度与(大部分)这些点。

但我也倾向于认为,Linq的特点之一是抽象数据库访问,使它看起来你只是在处理一堆集合,尽管懒惰的评估范例意味着那些集合直到您对它们运行查询才会被评估。我以同样的方式访问数据存储区似乎并不矛盾,就好像它是一个具体的内存中的集合。

还要记住,这是一个广泛而一致地使用这种模式的继承代码库,值得重构吗?我承认从一开始就使用Get方法可能会更好,但我还不确定使用索引器是完全不正确的。

我很想听听所有的意见,谢谢。

回答

0

我倾向于同意您的团队开发人员所建议的几乎所有内容,除了Guid部分。如果这里有任何问题,它必须在考虑性能的数据库级别上,而不是在代码中。

就我个人而言,我认为属性和索引器不应该隐藏long运行操作,尽管Users可以通过LINQ到SQL进行缓存。这就是为什么我会更喜欢一种方法。

我也同意从索引器返回null是不好的。改为抛出异常。

+0

- 由于连接已经建立,数据库查询可能不会像内存查询一样快吗? – fearofawhackplanet 2010-04-15 13:00:36

0

我认为他关于使用GUID作为索引器的观点可能是指它存储在数据库中。使用整数作为键将提供更好的性能,并且占用比使用GUID更少的存储空间。

如果索引(键)不在集合中,您将抛出异常,而返回null与索引器通常非常不常见。

就我个人而言,我并不是真的在这里看到这个问题,它几乎相当于有一个GetUser方法。我的意思是如果你想整理一下,你实际上可以引入一个叫做GetUser的私有方法,索引器可以调用例如

public IUser this[Guid userId] 
{ 
    get { return GetUser(userId); } 
} 

private IUser GetUser(Guid userId) 
{ 
    return (from u in _dataContext.Users 
      where u.Id == userId 
      select u).FirstOrDefault(); 
} 

从外观设计上来看来看,我个人也不会使用索引,我会去用GetUser方法。

+0

感谢您的意见。我没有看到你所建议的重构有任何好处,当然,要么保持原样,要么完全移除索引器。你正在改变内部或外部行为。除非我错过了这一点。 – fearofawhackplanet 2010-04-15 11:11:36

+0

@fearofawhackplanet:如果你阅读我发布的内容,我说*如果你想整理*。唯一的好处是可维护性和更干净的代码。我通常不喜欢在getter中放入那么多代码。关于长时间运行操作的 – James 2010-04-15 11:23:05