Dam*_*amb 3 c# lambda linq-to-entities entity-framework
我想根据使用其属性的函数的结果来过滤我的entites.
即.我有这样的实体:
public class Lorem
{
public int A {get;set;}
public int B {get;set;}
public int C {get;set;}
public double DoMath(int externalValue)
{
// real implementation is longer and more complex
if(A==B) {
// some calculations
return 0.2;
}
if(B==C) {
// some calculations
return 0.9;
}
else return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我正在查询实体,我想只获得DoMath> 0的那些实体.
// simplified scenario for example purpose
int someValue = 95;
// working with Entity Framework 4.1 Code First
var filtered = db.Lorems.Where(x=>x.DoMath(someValue) > 0);
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
LINQ to Entities无法识别方法-----,并且此方法无法转换为商店表达式.
有可能让它像这样工作吗?
我在定制lambda表达式和与代表一起工作方面的技巧很差,所以我想得到一些帮助.
编辑:这是'DoMath'功能真实代码(没有评论,因为它们不是英文):
public double VypocitejPrislusnost(int value)
{
if (A == B)
{
if (value <= C)
{
return 1;
}
if (value > D)
{
return 0;
}
else
{
double b = D - C;
double tangens = Math.Tan(1 / b);
double a = tangens * (D - value);
return Math.Round(a, 2);
}
}
if (C == D)
{
if (value >= B)
{
return 1;
}
if (value <= A)
{
return 0;
}
else
{
double b = B - A;
double tangens = Math.Tan(1 / b);
double a = tangens * (value - A);
return Math.Round(a, 2);
}
}
else
{
if (value >= B && value <= C)
{
return 1;
}
if (value <= A || value >= D)
{
return 0;
}
if (value > A && value < B)
{
double b = B - A;
double tangens = Math.Tan(1 / b);
double a = tangens * (value - A);
return Math.Round(a, 2);
}
if (value > C && value < D)
{
double b = D - C;
double tangens = Math.Tan(1 / b);
double a = tangens * (D - value);
return Math.Round(a, 2);
}
else
{
return 0;
}
}
}
Run Code Online (Sandbox Code Playgroud)
它基本上计算不同场景中三角形的y坐标.我用它来计算给定值适合模糊集的程度.
实体框架Where
期待一个表达式树,它将被转换为一个t-sql语句.不幸的是,你的DoMath
方法没有转换为t-sql,所以你必须将结果下拉到内存中,然后调用Where
你的方法.原因是一旦你的结果在内存中,LINQ方法就可以处理标准委托,而不是表达式树,所以对那里的内容没有任何限制
要做到这一点,只需要AsEnumerable()
在Where
将整个表格拉入内存的课程前面,所以只有在它相当小的情况下才这样做
var filtered = db.Lorems.AsEnumerable().Where(x => x.DoMath(someValue) > 0);
Run Code Online (Sandbox Code Playgroud)
当然,如果你能识别一些基本的情况下使用你的DoMath
将不大于0,则可以过滤这些结果出来了前面,用一个表达式树.这将减少来自数据库的结果.然后,您可以过滤内存中的其余部分.我不知道你的DoMath
方法做了什么(你暗示它比你的问题中列出的更复杂),但假设这样的事情应该有效:
var filtered = db.Lorems
.Where(x => x.A < 10 && x.B != x.C)
.AsEnumerable()
.Where(x => x.DoMath(someValue) > 0);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1797 次 |
最近记录: |