4

下面是我的代码。请审查它。

 1. bool isUnavailable = db.Deploys.Where(p => 
     p.HostEnvironmentId == Guid.Parse(host.ID) &&
     p.Status == (int)DeployStatus.Deploying).AsEnumerable().Any();

这个有效。

以下语句不起作用。

2. bool isUnavailable = db.Deploys.Where(p => 
    p.HostEnvironmentId == Guid.Parse(host.ID) &&
    p.Status == (int)DeployStatus.Deploying).Any();//Error 

例外是

    An exception of type 'System.NotSupportedException' occurred in 
Microsoft.Data.Services.Client.DLL but was not handled in user code
    
    Additional information: The method 'Any' is not supported.


3. bool isUnavailable = db.Deploys.Where(p => 
        p.HostEnvironmentId.ToString() == host.ID &&
        p.Status == (int)DeployStatus.Deploying).AsEnumerable().Any();//Error

例外是

    An exception of type 'System.NotSupportedException' occurred in 
      Microsoft.Data.Services.Client.DLL but was not handled in user code
      Additional information: The expression (([10007].HostEnvironmentId.ToString() == 
"b7db845b-cec4-49af-8f4b-b419a4e44331") And ([10007].Status == 90)) is not supported.

DeploysClass 是构建在 WCF Data 服务的客户端代理类中的模型。我正在使用“添加服务引用”来创建 WCF 客户端代理类。

但是对于通用列表,假设如下代码。它会正常工作。

4.bool b=servers.Where(d => 
   d.status == (int)Enums.ServerStatus.Deploying ||
   d.status == int)Enums.ServerStatus.Unavailable).Any();

我的问题是

为什么在不同的类中使用相同的方法得到不同的结果。(参见方法2和方法4)。

为什么2和3不起作用。

希望可以有人帮帮我 。谢谢

4

1 回答 1

5

LINQ 有一个“提供者”的概念。在不同的数据源上使用 LINQ 时,对于相同的 LINQ 查询,需要根据数据源进行不同的操作。

例如,当您想使用 LINQ 查询数据库时,需要将 LINQ 查询转换为 SQL 查询。当数据源为 OData 时,需要将查询转换为 URL。每个都有不同的提供程序,每个提供程序支持不同的 LINQ 运算符子集和其他语言结构。LINQ-to-SQL、Entity Framework 和 LINQ-to-NHibernate 是用于数据库访问的三个流行的 LINQ 提供程序。

在您的情况下,您正在使用 WCF 数据服务,其中包括 OData 的 LINQ 提供程序。由于在 OData 中无法表达.Any()LINQ 运算符,因此尝试在具有该提供程序的查询中使用它会引发异常。通过使用.AsEnumerable(),您实质上是在说停止使用 OData LINQ 提供程序并开始使用 LINQ-to-Objects 提供程序(从技术上讲,它不是提供程序,但从概念上讲,您可以将其视为一个提供程序)。这意味着只有之前.AsEnumerable()的内容将被转换为 OData 查询,从而检索所有Deploy匹配的实体.Where(),并且在它们全部传输到客户端之后,客户端将.Any()通过检查数量来执行Deploy它收到的实体。如果有很多这样的实体,这当然是不好的,当你想要的只是服务器端(可能是数据库)检查是否有任何实体时,它会导致不需要的数据通过网络传输。不幸的是,.Any()OData 1.0 不支持(我不知道 OData 2.0)。

此外,OData 可能也不支持.ToString()。您可能需要Guid直接比较结构,即创建一个包含您要比较的 GUID 值的局部变量:

var g = Guid.Parse("b7db845b-cec4-49af-8f4b-b419a4e44331")`

然后在查询中比较 GUID,如下所示:

x.HostedEnvironment == g
于 2012-08-26T11:09:16.403 回答