#c# #sql-server #api #asp.net-core #stored-procedures
#c# #sql-сервер #API #asp.net-core #хранимые процедуры
Вопрос:
По какой-то причине, когда я пытаюсь выполнить запрос (через API) с идентификатором записи, я получаю доступ, где он содержит нулевые атрибуты. Но, если я выполняю вопрос, используя другие атрибуты (помимо ID), он имеет правильные значения.
Например: когда я выполняю (фактический код хранимой процедуры):
CREATE PROCEDURE [dbo].[spClient_GetById]
@Id int
AS
BEGIN
SELECT *
FROM dbo.Client
WHERE Id = @Id;
END
Я получаю запись
{
"id": 2,
"firstName": null,
"lastName": null,
"email": null,
"phoneNumber": null,
"houseNum": "1212",
"street": "Downtown",
"state": "WA",
"city": "Vancouver",
"cost": 12000.0000,
"status": "Started",
"eta": 0,
"startDate": null,
"completeDate": null,
"contractorID": 0
}
Но когда я выполняю следующий запрос в той же базе данных,
CREATE PROCEDURE [dbo].[spClient_GetByHouse]
@HouseNum nvarchar(10),
@Street nvarchar(50) = null
AS
IF @Street IS NULL
BEGIN
SELECT *
FROM dbo.Client
WHERE HouseNum = @HouseNum;
END
ELSE
BEGIN
SELECT *
FROM dbo.Client
WHERE HouseNum = @HouseNum AND Street LIKE @Street;
END
Я получаю следующую запись (кстати, ту же запись):
{
"id": 2,
"firstName": "This",
"lastName": "That",
"email": "qwe@yahoo.com",
"phoneNumber": "3603602334",
"houseNum": "1212",
"street": "Downtown",
"state": "WA",
"city": "Vancouver",
"cost": 12000.0000,
"status": "Started",
"eta": 0,
"startDate": null,
"completeDate": null,
"contractorID": 1
}
Кроме того, если я выполняю SQL-код в SQL Server, он возвращает все правильные значения. Итак, проблема в том, что когда я вызываю эту хранимую процедуру через API, она возвращает нулевые значения, когда должна.
Кроме того, имя, фамилия и номера телефонов определены так, чтобы не допускать нулей в схеме
Дополнительная информация: вот функция вызова хранимой процедуры запроса my ID:
public async Task<ClientModel> GetProjectById(int id)
{
var records = await _dataAccess.LoadData<ClientModel, dynamic>("dbo.spClient_GetById", new { Id = id },
_connectionString.SqlConnectionName);
return records.FirstOrDefault();
}
И вот функция для вызова запроса по другим атрибутам:
public async Task<ClientModel> GetProjectByHouse(string house, string? street)
{
var p = new { HouseNum = house, Street = street };
var records = await _dataAccess.LoadData<ClientModel, dynamic>("dbo.spClient_GetByHouse", p,
_connectionString.SqlConnectionName);
return trimValues(records.FirstOrDefault());
// return records.FirstOrDefault();
}
И вот функция API для вызова любой из предыдущих функций:
public async Task<IActionResult> Get(int? projectId, string? house, string? street)
{
if (projectId != null)
{
var project = await _clientData.GetProjectById(projectId ?? default(int));
if (project == null)
return NotFound();
return Ok(project);
}
else if (house != null)
{
if (house.Length < 2)
return BadRequest();
var project = await _clientData.GetProjectByHouse(house, street);
if (project == null)
return NotFound();
return Ok(project);
}
else
{
return BadRequest();
}
}
Комментарии:
1. «когда я пытаюсь выполнить запрос (через API)». Можете ли вы опубликовать код C #, который вызывает сохраненную процедуру и возвращает неожиданные значения null? Я не вижу ничего плохого в T-SQL (игнорирование SELECT * является злом).
2. Согласен, здесь вообще нет C #, только json (что, мягко говоря, странно) и необработанный sql.
3. @Zer0 извините, просто добавил код. Надеюсь, это поможет отследить ошибку!
4. Я также не вижу ничего плохого в коде C #, и это странно, учитывая, что вы эффективно вызываете сохраненные процедуры таким же образом. Тем не менее, я понятия не имею, что
_dataAccess
есть и чтоLoadData
делает. Вы пробовали пошаговое выполнение с помощью отладчика? Если в схеме эти столбцы помечены как NOT NULL, это не может быть база данных. Что-то теряется при переводе.5. Я бы дважды проверил, является ли подключаемая в C # база данных такой же, где вы запускаете код. Другой вариант увидеть, какие значения передаются в хранимую процедуру, написав процедуру ведения журнала
Ответ №1:
Не уверен, что это решило проблему (но проблема решена). Мне пришлось удалить старую базу данных и опубликовать новую.
Ответ №2:
Есть два случая, которые я нашел
- С учетом регистра псевдоним должен совпадать с моделью.
- В хранимых процедурах, если столбец имеет тип данных integer, то модель также должна иметь тот же тип.