我遇到了EF和IQueryable的奇怪行为。
public IQueryable<foo> getFoo()
{
IQueryable<foo> query;
string someVar = functies.getSomeInt().ToString();
try
{
query = from sTable in db.someTable
from oTable in db.otherTable
where sTable.Id == oTable.Id
&& sTable.Var == someVar
select sTable;
} catch {}
return query;
}
public Test()
{
var queryFoo = getFoo();
foreach(var foo in queryFoo)
{
//This works fine
}
}
上面的示例运行得很好,但是当你在try块中放入someVar的声明时,EF似乎无法将sTable.Var与someVar进行比较。
public IQueryable<foo> getFoo()
{
IQueryable<foo> query;
try
{
string someVar = functies.getSomeInt().ToString();
query = from sTable in db.someTable
from oTable in db.otherTable
where sTable.Id == oTable.Id
&& sTable.Var == someVar
select sTable;
} catch {}
return query;
}
public Test()
{
var queryFoo = getFoo();
foreach(var foo in queryFoo)
{
//This doesn't work
//unable to create constant value of type 'foo'
}
}
这会导致“无法创建类型为'foo'的常量值。在此上下文中仅支持基本类型或枚举类型。”
为什么EF会以这种方式表现,是否有任何合理的解释? 我真的不明白它的区别,它可能与变量的范围有关。但它似乎仍然很奇怪。
到目前为止,我得到了什么研究(所以如果我按照下面的例子,当进一步嵌套时,someVar不是本地的???):
局部变量,例如下面的orderID变量 例如,在客户端进行评估。
int orderID = 51987;
IQueryable<SalesOrderHeader> salesInfo =
from s in context.SalesOrderHeaders
where s.SalesOrderID == orderID
select s;
另外
还在客户端上评估方法参数。 orderID参数传递给MethodParameterExample方法。
public static void MethodParameterExample(int orderID)
{
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
IQueryable<SalesOrderHeader> salesInfo =
from s in context.SalesOrderHeaders
where s.SalesOrderID == orderID
select s;
foreach (SalesOrderHeader sale in salesInfo)
{
Console.WriteLine("OrderID: {0}, Total due: {1}", sale.SalesOrderID, sale.TotalDue);
}
}
}
Literals and Parametesr on the Client
未改变:
public IQueryable<klassen> getKlassenPerGebruiker(Db.Models.gebruiker gbr)
{
// Connectie met de database maken.
var db = new Datastore.Db.Models.dataContext(); //of type DbContext
IQueryable<klassen> query;
try
{
string jaar = functies.getHuidigStartJaar().ToString();
query = from klas in db.klassens
from kpg in db.klassenpergebruikers
from sj in db.schooljaars
where kpg.Klassen_id == klas.Id
&& kpg.Gebruikers_id == gbr.Id
&& sj.Id == klas.Schooljaar_id
&& sj.Start == jaar
&& kpg.School_id == gbr.School_id
orderby klas.Naam
select klas;
}
catch
{
query = null;
}
}
调用函数;
IQueryable qklassen = gs.getKlassenPerGebruiker((user) Session["user"]);
if (qklassen != null)
{
foreach (klassen klas in qklassen)
{
}
}
答案 0 :(得分:1)
评估时会对其进行评估。当您实现查询时会发生这种情况(ToArray,FirstOrDefault等)。您返回查询 - 这就是问题所在。