【问题标题】:Returning IQueryable or Enumerated Object返回 IQueryable 或枚举对象
【发布时间】:2010-04-07 05:42:44
【问题描述】:

我想知道这两种场景之间的性能差异以及彼此之间的劣势是什么?

第一种情况:

public class Helper //returns IQueryable
{
   public IQueryable<Customer> CurrentCustomer
   {
      get{return new DataContext().Where(t=>t.CustomerId == 1);
   }
}

public class SomeClass
{
    public void Main()
    {
       Console.WriteLine(new Helper().CurrentCustomer.First().Name;
    }
}

第二种情况:

public class Helper //returns Enumerated result
{
   public Customer CurrentCustomer
   {
      get{return new DataContext().First(t=>t.CustomerId == 1);
   }
}

public class SomeClass
{
    public void Main()
    {
       Console.WriteLine(new Helper().CurrentCustomer.Name;
    }
}

提前致谢。

【问题讨论】:

    标签: c# linq iqueryable


    【解决方案1】:

    嗯,我可以看到的主要区别是执行查询的时间以及您可以对查询执行的其他操作。

    例如,假设您的Customer 对象有一些大字段。使用第二种方法,您将始终获取它们。使用第一种方法你可以写:

    string name = helper.CurrentCustomer.Select(x => x.Name).First();
    

    然后只需要查询数据库中的单个字段。就时间而言,查询只会在您实际请求数据时执行(这就是它能够等到您使用Select 来确定在上述情况下将什么放入查询之后)。这有利也有弊——它会使推理变得更加困难,但它也可以节省一些工作。在“推理”方面,你知道一旦你有了客户,你就有了一个可以与之合作的对象。但是,如果您使用相同的可查询对象两次,您需要知道您的 LINQ 查询提供程序是否会缓存结果……如果您这样写:

    IQueryable<Customer> currentCustomerQuery = helper.CurrentCustomer;
    Customer x = currentCustomerQuery.First();
    Customer y = currentCustomerQuery.First();
    

    会发出一次或两次查询吗?我怀疑这在很大程度上取决于提供商,但我不想对具体的做出任何猜测。

    要考虑的另一件事是使用您正在构建的 API 是否容易。就我个人而言,我通常会发现使用提供我想要的数据的 API 比我可以从中获取数据的查询更容易。另一方面,它不太灵活。

    一个选项是允许 both - 有一个 GetCurrentCustomerQuery() 和一个 GetCurrentCustomer() 方法。 (我自己可能不会将它们设为属性,但这只是个人喜好问题。)这样您就可以在真正需要时获得所需的灵活性,但有一种简单的方法可以将当前客户作为对象.

    【讨论】:

    • 您能解释一下为什么不将它们设为属性吗?谢谢。
    • @Tarik:感觉他们做的工作太多,不能成为属性——至少如果它实际上是在执行数据库查询的话。我通常不期望财产获取者做很多工作。另一方面,我猜很多 LINQ 都使用 确实 进行查询的属性,所以它会适应这种情况。不过这真的只是个人喜好。
    【解决方案2】:

    简而言之,使用 IQueryable 要好得多,它允许您进一步过滤返回的 IQueryable,而无需实际将对象或集合加载到内存中。在这种情况下,返回类型是一个简单的 Customer 类,影响很小,但在集合的情况下,强烈建议您使用 IQueryable。 Chris Sells 更深入地展示了这个问题here

    【讨论】:

      【解决方案3】:

      这两种方法的区别在于第一种方法返回的是一个可以返回对象的表达式,而第二种方法已经执行了表达式并返回了对象。

      在这种精确的场景中,差异不是很有用,并且将单个对象作为表达式返回也不是很直观。

      如果您有一个返回多个对象的方法,则这种差异更有用。表达式的延迟执行意味着您将只加载您实际使用的对象。如果您只需要前几个对象,则不会创建其余对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-17
        相关资源
        最近更新 更多