2012-12-21 144 views
6

我正在使用EF并且有一些查询。这是我的代码SELECT语句中的Linq静态方法

IEnumerable<Customer> customers = from c in context.Customers 
    select new Customer 
    { 
     ID = c.ID, 
     Name = c.Name, 
     LastName = c.LastName, 
     DepID = c.DepID, 
     Editable = SomeStruct.Check(c.DepID) 
    } 

public struct SomeStruct 
{ 
    public static bool Check(int depID) 
    { 
     //Here I have some logic 
    } 
} 

它工作正常。 但是,如果我声明SomeStructclass它将会失败。

我的问题是:

  1. 它为什么会发生?
  2. 使用静态函数是否强制查询执行?
+9

我可以证实:如果'SomeStruct'是'class',但该方法仍然是'static',那么它*不工作 - 我的理解是否正确?如果是这样:会发生什么?什么是例外? –

+0

当SomeStruct是一个struct时,你确定你的代码正在工作吗?你能否将ToList()添加到你的select语句中,看看是否所有东西都还在工作? –

回答

0

假设这是一个运行时问题,在许多情况下您正在描述,这是一个参考问题。 EF的linq提供程序支持调用在类中声明的静态方法(静态或非静态)。

  1. 我建议你到你的结构改变为一类,并使其静态帮你调查这个问题。

  2. 不,在您调用第一次迭代或客户之前不会执行任何操作。

希望这有助于

6

SomeStruct.Check(c.DepID)应转化为SQL查询代码的方法。这描述了类/结构等的行为。这是由于实体框架在类和结构中使用这些方法的不同工作。但是你可以做此项检查在客户端:

IEnumerable<Customer> customers = from c in context.Customers 
    select new 
    { 
     ID = c.ID, 
     Name = c.Name, 
     LastName = c.LastName, 
     DepID = c.DepID 
    } 
    .AsEnumerable() 
    .Select(d=>new Customer 
    { 
     ID = c.ID, 
     Name = c.Name, 
     LastName = c.LastName, 
     DepID = c.DepID, 
     Editable = SomeStruct.Check(c.DepID) 
    }); 

或者你也可以设置可编辑的属性为只读属性:

public class Customer{ 
    public int ID{get;set;} 
    public string Name{get;set;} 
    public string LastName {get;set;} 
    public Guid DepID{get;set;} 
    public bool Editable{get{return SomeStruct.Check(DepID);}} 
} 
1

这是容易复制你的代码不能使用LINQ工作的实体。 任何不能被翻译成sql的东西都会抛出一个运行时异常。在您的情况下:

NotSupportedException:LINQ to Entities不能识别方法的布尔检查(Int32)方法,并且此方法无法转换为存储表达式。

如果你得到了它在一些点上运行,不能一直都跟structclass差异,请参阅What's the difference between a static struct method and a static class method?

你可能改变别的东西的同时,像select前添加ToList()