代码之家  ›  专栏  ›  技术社区  ›  Eduardo Rosostolato

无法创建IdentityUserClaim类型的常量值

  •  0
  • Eduardo Rosostolato  · 技术社区  · 6 年前

    我知道你必须说这篇文章是重复的,但我已经读了多篇文章,答案对我的代码不起作用。

    这是一个ASP NET Web API服务器。看一看:

        // GET: api/Vessels
        [HttpGet, Route(""), Route("{assets}")]
        public IQueryable<Vessel> GetVessels(string assets = "all")
        {
            var user = GetUser();
    
            if (IsAdmin(user))
            {
                return assets == "all"
                    ? GetChildren(db.Vessels)
                    : db.Vessels;
            }
    
            var claims = user.Claims
                .Where(c => c.ClaimType == "vessel")
                .ToList();
    
            var vessels = db.Vessels
                .Where(v => claims.Any(c => v.Id == int.Parse(c.ClaimValue)))
                .toList(); // will evaluate the query and get error
    
            return assets == "all"
                ? GetChildren(vessels)
                : vessels;
        }
    

    这是一个例外:

    EntityFramework.sqlserver.dll中发生类型为“System.NotSupportedException”的异常,但未在用户代码中处理。 其他信息:无法创建类型为“Microsoft.aspnet.Identity.EntityFramework.IdentityUserClaim”的常量值。在此上下文中只支持基元类型或枚举类型。

    在我的测试中,我意识到错误在这个块中:

    claims.Any(c => v.Id == int.Parse(c.ClaimValue))
    

    如果我把它改成5或者其他什么,它就可以工作了!

    2 回复  |  直到 6 年前
        1
  •  1
  •   Steve Py    6 年前

    不幸的是,从字符串到int不是一个简单的方法,但是从int到string有一个方法。

    我认为这应该奏效:

    var vessels = db.Vessels
        .Where(v => claims.Any(c => SqlFunctions.StringConvert((double)v.Id) == c.ClaimValue))
        .ToList();
    

    最初的错误是Linq2ef传递int.parse,而int.parse又试图转到数据库,无法为联接形成有效的SQL,因此它出错。select上的int.parse在评估结果时可以由ef处理,这样您的工作可以解决,但会将“vessel”声明的整个ID集加载到.tolist()上的内存中。除非您处理的是非常大的数据集或大量的请求,否则这不太可能是一个问题。

    不过,理想情况下,您的FK类型应该与它们将要连接的pk相匹配,以避免类似的问题,但是对于现有的数据库,您通常必须接受给定的内容。:)

        2
  •  0
  •   Eduardo Rosostolato    6 年前

    好吧,我找到了一个工作,它可以工作:

    var claims = user.Claims
                .Where(c => c.ClaimType == "vessel")
                .Select(c => int.Parse(c.ClaimValue))
                .ToList();
    
    var vessels = db.Vessels.Where(v => claims.Any(c => v.Id == c));
    

    代码对我没有任何意义,有人能回答发生的事情吗?