Использование записи для обновления существующих записей в базе данных - PullRequest
0 голосов
/ 13 апреля 2020

Я пишу контроллер API, который вставляет и обновляет записи в таблице. Я могу легко добавлять новые элементы в базу данных, но мне сложно понять, как обновить существующие записи. Мое текущее решение состоит в том, чтобы запросить количество записей, которые имеют те же UserName и DeviceId, что и запрос. Если счет> 0, то мы выполняем запрос на обновление. Иначе мы выполняем запрос вставки. Но я не уверен, как вернуть количество записей из countQuery. Кроме того, я бы предпочел не использовать патч или поставить методы для этого. Я хочу все логи c в методе пост. Спасибо за вашу помощь!

public BaseResponse Post([FromBody]PendingAttachmentRequest pending)
    {
        var datasource = "";
        var appVersion = "";
        var sessionId = "";
        var updateQuery = "UPDATE PendingAttachments SET PendingCount = @PendingCount,LastUpdated = @LastUpdated,DataSource = @DataSource WHERE DeviceId = @deviceId AND WHERE UserName = @userName";
        var countQuery = "SELECT count(*) PendingAttachments WHERE DeviceId = @DeviceId AND WHERE UserName = @UserName";
        MobileCompleteServer.Helpers.Connection.GetHeaderInfo(out sessionId, out datasource, out appVersion);
        using (var onbaseConnection = MobileCompleteServer.Helpers.Connection.Connect(sessionId, datasource))
        {
            var connectionString = System.Configuration.ConfigurationManager.AppSettings["ConnectionString"];
            try
            {
                using (SqlConnection sqlConnection = new SqlConnection(connectionString))
                {
                    sqlConnection.Open();
                    using (SqlCommand comm = new SqlCommand(countQuery, sqlConnection))
                    {
                        if (/*how to check if the result of countQuery is > 0*/)
                        {
                            using (SqlCommand sqlComm = new SqlCommand(updateQuery, sqlConnection))
                            {
                                sqlComm.CommandType = System.Data.CommandType.Text;
                                //replace that row with request body
                                sqlComm.Parameters.Add(new SqlParameter("@DataSource", pending.DataSource));
                                sqlComm.Parameters.Add(new SqlParameter("@LastUpdated", pending.LastUpdated));
                                sqlComm.Parameters.Add(new SqlParameter("@PendingCount", pending.PendingCount));
                                sqlComm.Parameters.Add(new SqlParameter("@DeviceId", pending.DeviceId));
                                sqlComm.Parameters.Add(new SqlParameter("@UserName", pending.UserName));
                            }
                        }
                        using (SqlCommand sqlCommand = new SqlCommand("sp_InsertPendingAttachments", sqlConnection))
                        {
                            sqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
                            sqlCommand.Parameters.Add(new SqlParameter("@DataSource", pending.DataSource));
                            sqlCommand.Parameters.Add(new SqlParameter("@UserName", pending.UserName));
                            sqlCommand.Parameters.Add(new SqlParameter("@DeviceId", pending.DeviceId));
                            sqlCommand.Parameters.Add(new SqlParameter("@PendingCount", pending.PendingCount));
                            sqlCommand.Parameters.Add(new SqlParameter("@LastUpdated", pending.LastUpdated));
                            sqlCommand.ExecuteNonQuery();
                        }

                    }
                }
                return new BaseResponse();
            }
            catch (Exception e)
            {
                if (e.Message == Constants.SessionNotFound)
                {
                    return new BaseResponse
                    {
                        Exception = Constants.SessionNotFound,
                        ExceptionStackTrace = e.ToString()
                    };
                }
                else
                {
                    return new BaseResponse
                    {
                        Exception = Constants.PendingAttachmentError,
                        ExceptionStackTrace = e.ToString()
                    };
                }
            }
        }
    }

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

У вас еще нет метода, обслуживающего конечную точку GET, принимающего deviceId и userName в качестве параметров? Если не создать его и вызвать этот метод для проверки существования и, в зависимости от результата, вы либо вызовите обработчик update или insert. Таким образом, ваш API будет более RESTful и модульным, а значит, менее связанным с бизнес-логикой c и более тестируемым.

1 голос
/ 13 апреля 2020

Если вас не волнует, сколько там записей, и вы просто хотите проверить, существует ли хотя бы одна запись в таблице, используйте «существует». Это определенно улучшит производительность запросов. Поэтому вам нужно проверять только истинное или ложное условие: https://docs.microsoft.com/en-us/sql/t-sql/language-elements/exists-transact-sql?view=sql-server-ver15

Вам также необходимо использовать метод «ExecuteReader» / «ExecuteScalar»: Проверить, существует ли запись в база данных

Попробуйте использовать шаблон проектирования репозитория, который разделит ваши логи доступа к данным c и доменные логи c, а также поможет сделать ваш код тестируемым. Кроме того, Ваш метод делает много вещей одновременно, поэтому он нарушает принцип Единой ответственности.

...