Невозможно создать постоянное значение типа IdentityUserClaim - PullRequest
0 голосов
/ 23 мая 2018

Я знаю, вы должны сказать, что это сообщение дублируется, но я уже перешел на несколько сообщений, и ответы не работают с моим кодом.

Это сервер веб-API Asp net.Посмотрите:

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

и это исключение:

Исключение типа 'System.NotSupportedException' произошло в EntityFramework.SqlServer.dll, но не было обработано пользователемкод Дополнительная информация: невозможно создать постоянное значение типа «Microsoft.AspNet.Identity.EntityFramework.IdentityUserClaim».В этом контексте поддерживаются только примитивные типы или типы перечисления.

На моих тестах я обнаружил, что ошибка находится в этом блоке:

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

Если я изменю его на 5 иличто-нибудь еще, это работает!

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

К сожалению, нет простого способа перейти от строки к int, но есть способ перейти от int к строке ..

Я считаю, что это должно работать:

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

Первоначальная ошибка заключается в том, что Linq2EF передает int.Parse, который, в свою очередь, пытается перейти к БД и не может сформировать допустимый SQL для объединения, поэтому он ошибается.Int.Parse для Select может быть обработан EF, когда он оценивает результаты, так что ваш обходной путь будет работать, но загружает весь набор идентификаторов для заявок на «сосуд» в память в .ToList ().Это вряд ли будет проблемой, если вы не имеете дело с очень большими наборами данных или большим количеством запросов.

В идеале, хотя ваши типы FK должны соответствовать PK, к которым они будут присоединены, чтобы избежать подобных проблемНо с существующими базами данных вам часто приходится брать то, что вам дают.:)

0 голосов
/ 23 мая 2018

Ну, я нашел обходной путь, и он работает:

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

Код не имеет никакого смысла для меня, может кто-нибудь ответить, что случилось?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...