【问题标题】:LINQ query cannot evaluate GET parameter in StartsWithLINQ 查询无法评估 StartsWith 中的 GET 参数
【发布时间】:2015-05-21 19:57:51
【问题描述】:

我正在尝试通过 GET 请求(在 Angular.js 中)使用 .NET Web API 和使用 LINQ 和 MySQL db 的实体框架进行查询。

http://localhost/ProductsApp/api/clientes/GetByName/M

问题是 GET 传递的参数没有被评估并且我没有得到任何结果(即使根据调试器将name 正确设置为"M")。 但是,如果我硬编码一个字符串,我会得到预期的结果。

    [ActionName("GetByName")]
    public IEnumerable<cliente> GetByName(string name)
    {

        var query = from c in context.clientes where c.nome.StartsWith(name) select c;
        var query2 = from c in context.clientes where c.nome.StartsWith("M") select c;
        var query3 = context.clientes.Where(c => c.nome.StartsWith(name));
        var query4 = context.clientes.Where(c => c.nome.StartsWith("M"));

        return query.ToList();
    }

我的 WebApiConfig.cs 有以下几行:

config.Routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{name}",
    defaults: null
);

我认为 LINQ 在执行时会解析变量,如下所示(我删除了查询中不重要的部分):

query.ToString()
"SELECT [...] WHERE `Extent1`.`nome` LIKE 'p__linq__0%'"
query2.ToString()
"SELECT [...] WHERE `Extent1`.`nome` LIKE 'M%'"
query3.ToString()
"SELECT [...] WHERE `Extent1`.`nome` LIKE 'p__linq__0%'"
query4.ToString()
"SELECT [...] WHERE `Extent1`.`nome` LIKE 'M%'"

query2query4 都返回正确的值,而 queryquery3 则不返回。为什么?我怎样才能让它发挥作用?

【问题讨论】:

  • even though name is being set correctly to "M" 您似乎有一些非常令人信服的证据表明情况并非如此。你怎么知道name 被设置为M
  • @Servy 因为调试器告诉我。会不会弄错了?
  • @user2753837 您能否提供由 query.ToString() 生成的填充查询。 “LIKE 'p__linq__0%'”看起来不正确。它应该类似于“LIKE `@p__linq__0 + '%'”。看起来实体框架没有创建适当的参数。这就是为什么你会收到回复
  • @ Ockert "SELECT\r\n Extent1 . cliente_id , \r\n Extent1 .诺姆, \r\n Extent1 .电子邮件, \r\n Extent1 . endereco \r\nFROM cliente` AS Extent1\r\n WHERE Extent1.nome LIKE 'p__linq__0%'"`
  • 您使用的是什么版本的 EF?我用 EF 6 做了类似的事情,生成的查询和你的不一样。

标签: c# asp.net linq entity-framework asp.net-web-api


【解决方案1】:

这是 MySQL Entity Framework 6.9.5 报告的错误

错误 #74918:Entity Framework 6 的查询结果不正确: https://bugs.mysql.com/bug.php?id=74918

已在 MySQL Connector/Net 6.7.7 / 6.8.5 / 6.9.6 版本中修复。

变更日志: 使用 Entity Framework 6,传入对“StartWith”的字符串引用 子句会返回不正确的结果。

或者,一种解决方法是使用.Substring(0),这会强制实体不使用LIKE(可能会影响性能)。

var query = context.clientes.Where(c => c.nome.StartsWith(name.Substring(0)));

【讨论】:

    【解决方案2】:

    如果您有多个带参数的 GET 方法,那么您必须更改您的 WebApiConfig.cs

               config.Routes.MapHttpRoute(
                name: "ActionApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional });
    

    或另一种方法来做到这一点,你必须像这样在 WebApiConfig.cs 中硬编码你的控制器和操作

                config.Routes.MapHttpRoute(
                 name: "GetApi",
                 routeTemplate: "api/{controller}/{action}/{id}",
                 defaults: new { action = "GetByName", controller = "Your Controller" });
    

    你的行动:

    [HttpGet]
    public IEnumerable<cliente> GetByName(string name)
    {
    }
    

    这样称呼

            $.ajax({
            type: 'GET',
            url: 'localhost/ProductsApp/api/clientes/GetByName?Name='+ M,
            data: JSON.stringify({}),
            contentType: 'application/json',
            dataType: 'json',
            success: function (data) {
    
                }
            }
        });
    

    【讨论】:

    • 我用配置文件更新了问题。我也尝试了你的可能性,但它仍然不起作用
    【解决方案3】:

    你的name参数不等于“M”,这个值有可能是null。 WebApi 可能需要一个“id”参数而不是“name”

    添加路由属性以确保将正确的值传递给名称参数

    [Route("api/clientes/GetByName/{name}")]
    public IEnumerable<cliente> GetByName(string name)
    {
        ....
    }
    

    【讨论】:

    • 也许我应该说我的WebApiConfig.cs有以下几行config.Routes.MapHttpRoute( name: "ApiByName", routeTemplate: "api/{controller}/{action}/{name}", defaults: null );调试器告诉我name"M"
    • 你有多个带参数的Get方法
    • @DineshChauhan 唯一带参数的其他 get 方法是接收 id (.../api/clientes/id) 的默认方法。调试时,调用正确的方法
    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 2020-07-24
    相关资源
    最近更新 更多