C# 1000+;Linq查询或数据库中的逻辑…哪个更糟?

C# 1000+;Linq查询或数据库中的逻辑…哪个更糟?,c#,performance,linq-to-sql,domain-driven-design,C#,Performance,Linq To Sql,Domain Driven Design,我是在一次采访中问这个问题的,考虑到篇幅,我没有得到答案这一事实并不奇怪,所以我想我应该更切题 我必须根据用户分配给特定客户的任务来决定显示什么。域对象看起来像这个大大简化的示例: public class Customer { public string Name { get; set; } public IEnumerable<Users> AssignedUsers { get; set; } } 公共类客户 { 公共字符串名称{get;set;} 公共IEn

我是在一次采访中问这个问题的,考虑到篇幅,我没有得到答案这一事实并不奇怪,所以我想我应该更切题

我必须根据用户分配给特定客户的任务来决定显示什么。域对象看起来像这个大大简化的示例:

public class Customer
{
    public string Name { get; set; }
    public IEnumerable<Users> AssignedUsers { get; set; }
}
公共类客户
{
公共字符串名称{get;set;}
公共IEnumerable AssignedUsers{get;set;}
}
在现实世界中,我还将评估他们是否拥有查看此特定客户的权限(使用安全标志的位比较),即使他们没有直接分配给它

我在这里试图坚持(DDD)原则。另外,我正在使用LINQtoSQL进行数据访问。在我的服务层,我向请求客户列表的用户提供信息,目前大约有1000项,每月增长约2%

如果我严格要求在服务层中保留逻辑,我将需要使用Linq执行
。其中
,以评估
AssignedUsers
列表是否包含请求列表的用户。这将导致在系统通过枚举时对每个
客户进行级联查询。我没有做任何测试,但这似乎效率低下

如果我在数据中伪造了no逻辑,那么我可以简单地使用
getCustomerByUser()
方法来执行
EXISTS
类型的SQL查询,同时评估安全性。这肯定会快得多,但现在我要说的是逻辑潜入数据库,这可能会在以后产生问题

我敢肯定,这是人们在推出Linq时经常遇到的一个问题……关于哪种方式更好,有什么建议吗?Linq的多个查询的性能是否比数据库中的逻辑更好?

哪个更差? 这取决于你问谁

如果你问DDD超纯粹主义者,他们可能会说数据库中的逻辑更糟糕

如果你问其他人,尤其是你的终端用户、实用主义开发人员以及为硬件和软件开发付费的人,他们可能会说性能的大幅下降更糟糕

DDD有很多值得推荐的地方,就像许多其他设计方法一样,但是如果你教条式地遵循它们,以牺牲真实世界的考虑因素(如性能)为代价提出“纯”设计,它们都会失败

如果您真的需要对数据执行这种查询,那么数据库几乎肯定会更好地执行这项任务

或者,你在这里“错过了一个技巧”。你的设计,然而DDD,实际上是不对的吗


总体-适当使用您的工具。无论如何都要努力使逻辑在服务层中保持干净的分离,但不要在该逻辑正在进行大量数据库设计工作时进行分离。

如果AssignedUser已正确映射(即,Association由Linq2SQL设计器生成,或者您具有带有AssociationAttribute的mark属性(或者来自名称空间的其他名称,我现在不确定),Linq2Sql将把linq查询转换为SQL命令,并且不会为每个客户迭代AssingedUser

也可以使用“反向”查询,如

from c in Customer
join u in Users on c.CustomerId equals u.AssignedToCustomerId // or other condition links user to customer
where <you condition here>
select c
来自客户中的c
在c.CustomerId等于u.AssignedToCustomerId//或其他条件链接用户到客户
哪里
选择c

LINQ是一个抽象概念,它将一系列功能封装到一个漂亮的小软件包中,上面有一颗大心脏

对于任何抽象,您都会得到开销,主要是因为事情并没有您或我想要的那么高效。MS在使LINQ非常高效方面做了大量工作

逻辑应该在需要的地方。Pure很好,但如果您要提供服务或产品,您必须牢记以下几点(这些没有特定顺序):

  • 维护。在它发布后,您是否能够轻松地完成一些工作,而无需将整个东西拆开
  • 可伸缩性
  • 演出
  • 可用性
  • 第三点是使用web时最重要的方面之一。您会在SQL Server上进行三角运算吗?不会。您会根据输入参数筛选结果吗?是的

    SQL Server是为处理海量查询、过滤、排序和数据挖掘而构建的。它在这方面蓬勃发展,所以让它来做吧


    这不是一个逻辑爬行,而是将功能放在它所属的地方。

    我个人会选择存储过程。这是适合这项工作的工具。 不使用它可能是一个不错的设计选择,但在我看来,设计范例是用来指导你的,而不是约束你的。 另外,老板只关心绩效:-)

    如果我严格要求在我的服务层中保留逻辑,我将需要使用Linq进行测试。其中,评估AssignedUsers列表是否包含请求列表的用户。这将导致在系统枚举时对每个客户进行级联查询。我没有做任何测试,但这似乎效率低下

    应该不需要枚举本地客户集合

    LinqToSql的主要用途是允许您在服务层中声明逻辑,并在数据层中执行该逻辑

    int userId = CurrentUser.UserId;
    
    IEnumerable<Customer> customerQuery =
      from c in dataContext.Customers
      where c.assignedUsers.Any(au => au.UserId = userId)
      select c;
    
    List<Customer> result = customerQuery.ToList();
    
    int userId=CurrentUser.userId;
    IEnumerable customerQuery=
    来自dataContext.Customers中的c
    其中c.assignedUsers.Any(au=>au.UserId=UserId)
    选择c;
    列表结果=customerQuery.ToList();
    
    我认为最好将您的模型描述为Customer类和User类之间的多对多关系。每个用户引用相关客户的列表,每个客户引用相关用户的列表。从数据库的角度来看,这是使用联接表表示的(根据微软的LINQtoSQL术语,他们称之为“连接表”)

    多对多关系是LINQtoSQL不支持的一个特性