实体框架:何时评估变量

时间:2016-01-25 20:44:53

标签: c# entity-framework iqueryable

我遇到了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)
                {
                }
            }

1 个答案:

答案 0 :(得分:1)

评估时会对其进行评估。当您实现查询时会发生这种情况(ToArray,FirstOrDefault等)。您返回查询 - 这就是问题所在。