Yield return database records using LinqToSql?

后端 未结 3 2016
长发绾君心
长发绾君心 2021-01-01 03:17

I have a supplying method in DAL:

public IEnumerable GetRecords()
{
    using (LinqDataContext context = new LinqDataContext())
    {
              


        
相关标签:
3条回答
  • 2021-01-01 03:44

    In the case of executing a basic query, it can work that way (certainly it is possible) - however, in the case of querying a naked Table<T>, it might be that it all buffers first; you could perhaps try querying the count during the iteration, or running a trace. In this case I suspect it will buffer first.

    Re closed: that also depends ;p If someone is using foreach, then yes: since foreach explicitly disposes the iterator via finally. However! It is not guaranteed if someone does, for example (very naughty and lax):

    var iter = yourData.GetEnumerator();
    if(iter.MoveNext()) {
        Console.WriteLine(iter.Current.Name); // first record of, say, 20
    }
    // and don't dispose the iterator == bad
    

    then since the iterator doesn't a: get disposed, b: exhaust itself, and c: doesn't crash, it won't shut down properly (any of those 3 conditions will close it properly). Emphasis: this is a pathological case: normally it is reasonably safe to say "it will close, yes".

    If you want guaranteed non-buffering, note that "dapper" has that, if you set buffered to false:

    IEnumerable<Customer> customers = connection.Query<Customer>(
           "select * from Customer", buffered: false);
    

    (it can also handle the parameters etc)

    0 讨论(0)
  • 2021-01-01 03:47

    1) yield will not necessarily be faster to get all values, but it would allow the code to start handling results before the database has returned all results. That is, yield returns the first result the instant it shows up, while ToArray() needs to wait for all results to show up before returning. Of course, if the underlying providers return all results at once due to buffering or other reasons, this may not make a difference.

    2) Yes, using will dispose of the LinqDataContext no matter how you exit the using block (exceptions/return/break/...)

    0 讨论(0)
  • 2021-01-01 03:57
    1. The iterator will be lazily evaluated. It will pull the first item and then "yield" it to its consumer. Performance impact will depend on how the LinqDataContext is implemented (it may cache stuff internally). Using ToArray(), or ToList(), will force all elements out of LinqDataContext before proceeding. Therefore, using ToArray() will make you yield nothing until LinqDataContext has returned every element. Whether that is optimal or not, is up to you.
    2. Yes, the "using" will be enforced properly.
    0 讨论(0)
提交回复
热议问题