Hug*_*une 8 c# linq lambda expression-trees linq-to-sql
我有一个数据库表Item,并使用linq-to-sql访问它.
我可以为Items定义一个自定义方法IsSpecial(),如果Item.id的平方根是偶数,则返回true:
partial class Item
{
public static Expression<Func<Item, bool>> IsSpecial = (i => Math.Sqrt(i.Id)%2==0);
}
Run Code Online (Sandbox Code Playgroud)
然后我可以在linq-to-sql查询中使用该属性,如下所示:
datacontext.Item.Where(Item.IsSpecial)
Run Code Online (Sandbox Code Playgroud)
现在出于审美原因,我想让IsSpecial非静态并修改它,所以我可以像这样调用它:
datacontext.Item.Where(i => i.IsSpecial())
Run Code Online (Sandbox Code Playgroud)
理想情况下,这也允许组合语句,上述(工作)snytax不允许:
datacontext.Item.Where(i => i.IsSpecial() && i.Id >100)
Run Code Online (Sandbox Code Playgroud)
定义此方法的正确语法是什么?
这不起作用:
partial class Item
{
public Expression<Func<bool>> IsSpecial = ( () => Math.Sqrt(this.Id)%2==0 );
// 'this' keyword not available in current context
}
Run Code Online (Sandbox Code Playgroud)
编辑: 我开始怀疑我要求的语法根本不允许
我想我可以忍受 datacontext.Item.Where(Item.IsSpecial).Where(i => i>100)
小智 4
Run Code Online (Sandbox Code Playgroud)partial class Item { public static Expression<Func<Item, bool>> IsSpecial = (i => Math.Sqrt(i.Id)%2==0); }
建议:添加readonly关键字。
然后我可以在 linq-to-sql 查询中使用该属性,如下所示:
Run Code Online (Sandbox Code Playgroud)datacontext.Item.Where(Item.IsSpecial)
是的,因为Where接受类型为 的参数Expression<Func<Item, bool>>,即Item.IsSpecial。
现在出于美观原因,我想让 IsSpecial 成为非静态的并修改它,这样我就可以这样调用它:
Run Code Online (Sandbox Code Playgroud)datacontext.Item.Where(i => i.IsSpecial())
这不起作用的原因是因为它IsSpecial不是一个函数,而是一个表达式树。()只能应用于函数。表达式树描述了一个函数,但不是一个函数。您可以使用以下命令创建真实函数expression.Compile():
datacontext.Item.Where(i => (IsSpecial.Compile()) (i))
Run Code Online (Sandbox Code Playgroud)
然而,这是行不通的,因为再次Where传递了一个表达式树,但IsSpecial.Compile()实际上并没有被调用。LINQ to SQL 尝试将其转换为 SQL,但由于无法识别而失败Expression.Compile,并引发异常。
但是,如果您可以(IsSpecial.Compile())在 LINQ to SQL 看到它之前进行替换...
这就是LINQKit 的用武之地:
它只提供了一点表达式树操作来使其工作。
datacontext.Item.AsExpandable().Where(i => (IsSpecial.Compile()) (i))
Run Code Online (Sandbox Code Playgroud)
创建.AsExpandable()一个包装器datacontext.Item来预过滤表达式。
理想情况下,这还允许组合语句,而上述(工作)snytax 不允许:
Run Code Online (Sandbox Code Playgroud)datacontext.Item.Where(i => i.IsSpecial() && i.Id >100)
没问题:
datacontext.Item.AsExpandable().Where(i => (IsSpecial.Compile()) (i) && i.Id > 100)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1006 次 |
| 最近记录: |