Как я могу получить элемент по строковому ключу с помощью веб-API? - PullRequest
1 голос
/ 29 мая 2020

Я не могу понять, как попасть в конечную точку вроде «api / GetItems / AB123» (AB123, конечно, является строкой) и вернуть этот элемент из моего набора данных. Я прочитал документацию по методу FindAsyn c (), и мне показалось, что это указывает на то, что он примет строку по умолчанию. Есть ли что-то, что мне нужно сделать с id, прежде чем передавать его в FindAsyn c ()? Моя БД не имеет первичного ключа, если это важно. (Я тоже не могу это изменить, это устаревшие данные, и я не могу контролировать схему)

В моей базе данных нет поля PK ID. Мне нужно сделать следующее и настроить таргетинг на уникальное строковое поле.

Мой метод GET:

        // GET: api/Items/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Item>> GetItem(string id)
        {
            var item = await _context.Items.FindAsync(id); // Error happens here: "InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Int64'."

            if (item == null)
            {
                return NotFound();
            }

            return item;
        }

Соответствует моей модели:

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string ItemId { get; set; }

Ответы [ 3 ]

0 голосов
/ 29 мая 2020

Из вашей ошибки очевидно, что в методе FindById ожидается int. Можете ли вы проверить тип поля в базе данных, но исходя из вашей модели, я бы сказал, что у вас нет правильного типа. Строка не может использоваться в качестве идентификатора таким образом, потому что SQL сервер не знает, как сгенерировать для этого значение.

Вы можете проверить этот пост для получения более подробной информации об этом: DatabaseGeneratedOption.Identity не генерирует идентификатор

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

Если это не так, и вы это делаете есть строка в базе данных, вы должны просто получить элемент с помощью метода SingleAsyn c (обратите внимание, что он выдаст исключение, если идентификатор неверен).

var item = await _context.Items.SingleAsync(e => e.ItemId == id);

Если вы не хотите исключения, если идентификатор не существует, вы можете использовать:

var item = await _context.Items.SingleOrDefaultAsync(e => e.ItemId == id);

, который вернет null для несуществующего идентификатора.

0 голосов
/ 02 июня 2020
    // GET: api/Items/5
    [HttpGet("{id}")]
    public async Task<ActionResult<Item>> GetItem(string id)
    {
        var item = await _context.Items.SingleAsync(x => x.ItemId == id);

        if (item == null)
        {
            return NotFound();
        }

        return item;
    }
0 голосов
/ 29 мая 2020

Привет и добро пожаловать в Сообщество по переполнению стека !!

Вместо find вы можете использовать .SingleAsyn c (), как показано ниже. Вы также можете сделать .Where (x => x.ItemId == id) .SingleAsyn c (). Но это зависит от вас.

        // GET: api/Items/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Item>> GetItem(string id)
        {
            var item = await _context.Items.SingleAsync(x => x.ItemId == id);

            if (item == null)
            {
                return NotFound();
            }

            return item;
        }
...