【问题标题】:Linq static method in SELECT statementSELECT 语句中的 Linq 静态方法
【发布时间】:2012-12-08 19:16:16
【问题描述】:

我正在与 EF 合作并有一些疑问。这是我的代码

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
    }
}

它工作正常。 但是,如果我将SomeStruct 声明为class,它将失败。

我的问题是:

  1. 为什么会这样?
  2. 使用静态函数会强制执行查询吗?

【问题讨论】:

  • 我可以确认一下:如果SomeStructclass,但方法仍然是static,那么它不起作用 - 我理解正确吗?如果是这样:会发生什么?有什么例外?
  • 当 SomeStruct 是一个结构体时,你确定你的代码能正常工作吗?您能否将 ToList() 添加到您的 select 语句中,看看是否一切正常?

标签: c# entity-framework linq-to-entities linq-to-objects


【解决方案1】:

在您的代码方法中,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)
    });

或者您可以将 Editable 属性设置为只读属性:

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);}}
}

【讨论】:

    【解决方案2】:

    很容易重现您的代码无法使用 linq to 实体。 任何无法翻译成 sql 的东西都会抛出运行时异常。在你的情况下:

    NotSupportedException:LINQ to Entities 无法识别方法“Boolean Check(Int32)”方法,并且该方法无法转换为存储表达式。

    如果你让它在某个时候运行,那可能与 structclass 的差异无关,请参阅 What's the difference between a static struct method and a static class method?

    您可能同时更改了其他内容,例如在select 之前添加ToList()

    【讨论】:

      【解决方案3】:

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

      1. 我建议您将结构更改为类并将其设为静态以帮助您调查问题。

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

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-18
        • 1970-01-01
        • 2022-07-29
        • 2021-12-17
        相关资源
        最近更新 更多