使用LinqToSql返回数据库记录?

net*_*rog 5 c# sql-server-2008 linq-to-sql

我在DAL有一个供应方法:

public IEnumerable<RecordType> GetRecords()
{
    using (LinqDataContext context = new LinqDataContext())
    {
        var records = context.RecordTable;

        foreach (RecordType record in records)
        {
            yield return record;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用者方法使用foreach循环中的记录.这样我想通过不缓存所有记录来节省内存使用量RecordTable,因为LinqToSql在场景后面使用DataReader.

我对这个场景有两个问题:

  1. 上面的yi​​eld-returns是否真的可以节省资源并且比将所有记录缓存到数组(.ToArray())更快?

  2. 如果在消费方法usingforeach循环内发生错误,或者如果消费方法将foreach在中间打破循环(如找到所需的记录和break),数据连接是否会自动正确关闭(我的意思是语句)?

Mar*_*ell 3

在执行基本查询的情况下,它可以以这种方式工作(当然这是可能的) - 但是,在查询 bare 的情况下Table<T>,它可能首先全部缓冲;您也许可以尝试在迭代期间查询计数,或运行跟踪。在这种情况下,我怀疑它会首先缓冲。

重新关闭:这也取决于;p 如果有人正在使用foreach,那么是:因为foreach通过 显式处置迭代器finally。然而!不能保证是否有人这样做,例如(非常顽皮和松懈):

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

那么由于迭代器不会 a: 被释放,b: 耗尽自身,并且 c: 不会崩溃,所以它不会正确关闭(这 3 个条件中的任何一个都会正确关闭它)。强调:这是一个病态的情况:通常来说,说“它会关闭,是的”是相当安全的。

如果您想要保证非缓冲,请注意“dapper”具有该功能,如果您设置bufferedfalse

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

(它还可以处理参数等)