我一直在读“我列举的东西不会马上跑掉”。所以我想找出查询列表的最佳方法。
下面是我的getAll方法。然后是我的过滤方法。然后是首选筛选方法(可读性)。
我的问题是,第三种方法是否与直接查询相同?换句话说,它会,还是不会从DB加载所有的myObjects,然后进行筛选?或在从DB.获取时进行筛选。
public static IEnumerable<myObject> getAll()
{
using (var db = Database.OpenConnectionString(blahblah))
{
var queryResults = db.Query("SELECT * FROM vu_myObjects");
return queryResults .Select(x => new myObject(x.myObjectName, x.myObjectF));
}
}
public static IEnumerable<myObject> getAllForFilter(String filter)
{
using (var db = Database.OpenConnectionString(blahblah))
{
var queryResults = db.Query("SELECT * FROM vu_myObjects WHERE ObjectF = @0", filter);
return queryResults.Select(x => new myObject(x.myObjectName, x.ObjectF));
}
}
public static IEnumerable<myObject> getAllForFilter(String filter)
{ // Not checked syntax.
return getAll().Where(x => x.ObjectF = filter);
}或者,如果你有更好的建议,我会全神贯注的。
发布于 2013-01-10 11:37:40
它会,还是不会从DB加载所有的myObjects,然后进行过滤?
它不会,因为您还没有真正查询数据库。因此,为了实际返回结果集,需要执行查询,IQueryable<T>已经推迟了测试。这可以通过几种方式来完成,例如调用ToList或迭代列表。
任何过滤,即您的Where子句,都将在DB端完成。
实际上,您目前的代码甚至无法工作-它将抛出一个ObjectDisposedException,因为您正在尝试在处理数据上下文之后对延迟的查询应用一个筛选器。要使代码正常工作,需要将where子句作为参数传递给getAll方法。
public static IEnumerable<myObject> getAll(Expression<Func<myObject,bool>> where)
{
using (var db = Database.OpenConnectionString(blahblah))
{
var queryResults = db.Query("SELECT * FROM vu_myObjects");
if (where != null)
{
queryResults.Where(where);
}
return queryResults .Select(x => new myObject(x.myObjectName, x.myObjectF));
}
}
public static IEnumerable<myObject> getAllForFilter(String filter)
{ // Not checked syntax.
return getAll(x => x.ObjectF = filter);
}更新
正如您刚才指出的,您使用的是WebMatrix.Database,由于这里没有延迟执行,所以上述任何一个都不适用。查询方法将立即执行,并返回IEnumerable<T>的结果集,因此应用后的任何筛选都将在内存中完成。因此,就效率而言,第一种筛选方法会更好,因为它可以在DB端完成所有工作。
您可以通过将Where子句转换为实际字符串并将其附加到查询中,从而获得可读性和效率。
发布于 2013-01-10 11:31:35
基本上是一样的。在实际查询从IEnumerable调用返回的getAlLForFilter之前,它将是一个评估迟缓的查询。如果对其调用.ToList()或访问内容,那么此时它将对数据库进行调用。如果在第三个调用中设置了一个断点,那么在告诉调试器计算查询之前,它将不会包含查询的结果。
https://stackoverflow.com/questions/14256764
复制相似问题