C# 使用实体'的结果;使用lambda表达式或linq查询进行筛选的s方法
我想根据处理实体属性的函数的结果筛选实体 我得到了这样的实体:C# 使用实体'的结果;使用lambda表达式或linq查询进行筛选的s方法,c#,entity-framework,lambda,linq-to-entities,C#,Entity Framework,Lambda,Linq To Entities,我想根据处理实体属性的函数的结果筛选实体 我得到了这样的实体: 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
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;
}
}
现在我正在查询实体,我只想得到那些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);
我收到以下错误:LINQ to Entities无法识别方法------,此方法无法转换为存储表达式。 有可能让它像这样工作吗?
我在自定义lambda表达式和处理代理方面的技能非常差,因此我希望得到一些帮助 编辑:这是“DoMath”函数的真实代码(没有注释,因为它们不是英文的):
public双精度vypocitejprislusnot(int值)
{
如果(A==B)
{
if(值D)
{
返回0;
}
其他的
{
双b=D-C;
双tangens=数学Tan(1/b);
双a=tangens*(D-值);
返回数学四舍五入(a,2);
}
}
如果(C==D)
{
如果(值>=B)
{
返回1;
}
如果(值=B&&A&&B值C&&值
它基本上是在不同场景下计算三角形中的y坐标。我用它来计算给定值在模糊集合中的适合程度。实体框架的
,其中
需要一个表达式树,它将转换为t-sql语句。不幸的是,没有将您的DoMath
方法转换为t-sql,因此您必须将结果向下拉入内存,然后调用Where
。原因是,一旦结果存储在内存中,LINQ方法将在标准委托上工作,而不是在表达式树上工作,因此对可以放入其中的内容没有限制
要做到这一点,只需在Where
前面钉上一个AsEnumerable()
——当然这会将整个表拖到内存中,所以只有当它相当小时才这样做
var filtered = db.Lorems.AsEnumerable().Where(x => x.DoMath(someValue) > 0);
当然,如果您可以确定一些基本情况,在这些情况下,DoMath
将不大于0,那么您可以使用表达式树预先筛选这些结果。这将减少来自数据库的结果。然后,您可以在内存中过滤其余部分。我不知道你的DoMath
方法做了什么(你暗示它比你问题中列出的更复杂),但假设这样的方法会起作用:
var filtered = db.Lorems
.Where(x => x.A < 10 && x.B != x.C)
.AsEnumerable()
.Where(x => x.DoMath(someValue) > 0);
var filtered=db.Lorems
其中(x=>x.A<10&&x.B!=x.C)
.可计算的()
其中(x=>x.DoMath(someValue)>0);
比我快。回答得好。通常我也会说,另一种选择是注册一个可以在数据库上调用的SQL函数,但我认为对于数学处理来说,这是一个糟糕的选择。@StriplingWarrior-我得到的印象是,他的实际DoMath方法更复杂;但是,如果它真的像他描述的那么简单,那么是的,你说的是Hanks,我正在处理你的答案,所以给我一点时间:)我将用DoMatg函数编辑我的Q,当有ppl试图找到更简单的解决方案时。谢谢,你设置为AsEnumerable()的解决方案很有效,适用于我的场景,因为我不会有很多记录(现在大约30张)+我会等一段时间再结束这个。当然-很高兴我能帮上忙!您只需要通过DoMath方法进行解析,然后缓慢但肯定地得出A、B、C和D的值,这些值不会生成您要查找的值,并将它们排除在针对数据库的linq查询中,然后将剩余的内容(通过使用AsEnumerable)拉入内存,并通过在第二个lambda中实际调用DoMath来过滤其余内容
var filtered = db.Lorems
.Where(x => x.A < 10 && x.B != x.C)
.AsEnumerable()
.Where(x => x.DoMath(someValue) > 0);