LINQ: 何时使用编译查询?

10

我希望得到一些专家意见。我之前使用过编译查询,但对于这种特殊情况,我不确定是否适用。

这是一个搜索表单,查询会根据正在搜索的内容而变化。

static Func<DBContext, int, IQueryable<Foo>> Search = CompiledQuery.Compile(
    (DBContext db, int ID) =>
        db.Person
            .Where(w => w.LocationID = ID)
            .Select(s => 
                new Foo 
                { 
                    Name = s.PersonName, 
                    Age = s.Age,
                    Location = s.LocationName,
                    Kin = s.Kin
                }));

现在如果有人填写了搜索框,我想要通过添加另一个Where语句来扩展查询:

var query = Search(context, 123);
query = query.Where(w => w.Name.Contains(searchString));
所以我的问题是,它是否返回所有LocationID == 123的结果,然后检查结果是否匹配searchString?还是它实际上扩展了编译查询?
如果是前者(我认为是),应该放弃CompiledQuery,只需创建一个扩展查询的方法,然后将其作为列表返回?
此外,CompiledQuery的最佳实践是什么,何时应该使用它们的指南是什么?
注意:我在使用带有Linq to SQLASP.NET网站。不确定是否有任何区别。
谢谢

一个典型的搜索需要多长时间/有多少记录?如果你正在搜索100,000行数据,而且只需要几秒钟的时间,那么与正确索引表相比,预编译LINQ查询是微不足道的一部分。 - mellamokb
这个表只有几千行。 - mnsr
4个回答

3
问题在于编译查询是固定的,它知道将对数据库运行哪个SQL。然而,Lambda表达式是惰性加载的,并且在运行时无法修改已编译的查询。坏消息是它将返回数据库中的所有记录,但它会在内存中查询这些记录以进一步细化它们。
如果您想编译查询,则建议编写两个具有不同签名的查询。

0

只需在编译的查询中包含您的附加条件即可。

DB.Person.Where(w => w.LocationID == ID 
                     & (searchString=="" || w.Name.Contains(searchString)))

那不是问题的重点。我只是用它作为扩展查询的示例。因此,还有其他条件性扩展查询的选项。 - mnsr
1
那么,我想你的问题标题应该是“你能在不重新编译的情况下扩展已编译的Linq查询吗?如果可以,怎么做?”我怀疑除非进行一些极其复杂的IL操作,否则不可能实现。这就是为什么它被称为“已编译”查询的原因。 - Robert Harvey
请注意,如果您在仅有几千行的表上进行查询,则编译查询所获得的性能优势可能微不足道。 - Robert Harvey

0
如果我没错的话,你需要在LINQ中使用一些动态where子句。因此,我建议你这样做。
IEnumerable list;

if(condition1)
{
  list = Linq Statement;
}

if(condition2)
{
  list = from f in list where con1=con && con2=con select f;
}

if(condition3)
{
 list = from n in list  con1=con && con2=con select f;
}

希望你听懂了我的话。


0
据我所知,编译查询一次是一个好的实践,这就是预编译查询的全部意义(这也是为什么您的预编译查询是静态的),它可以将查询编译成SQL以节省时间。如果扩展了预编译查询,则会再次编译该查询,这样就会失去优势。
在结果上查询结果(您的查询变量)不再是LINQ to SQL。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接