Проблема с логикой при передаче данных в хранимую процедуру EF в C # - PullRequest
0 голосов
/ 14 марта 2019

У меня есть хранимая процедура с 13 параметрами в базе данных SQL Server.И в моем приложении C # мне нужно вставить данные в эту хранимую процедуру, и я могу вставлять по 1 значению за раз, но мне нужно иметь возможность вставлять несколько значений, таких как 5 или 10 или более.У меня есть 5 массивов, которые будут иметь много значений для вставки в эту хранимую процедуру, но не вставляются, если массивы имеют более 1 значения, я думаю, что мой цикл выполнен неправильно.

Пожалуйста, посмотрите ниже.

Класс, который создаст метод для хранимой процедуры

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BarcodeReceivingApp.Persistence;
using BarcodeReceivingApp.Persistence.Repositories;

namespace BarcodeReceivingApp.Functionality
{
    public class StoredProcedureInsert
    {
        private readonly BarcodeReceivingFootPrintDbContext _barcodeReceivingFootPrintDbContext = new BarcodeReceivingFootPrintDbContext();

        public void CallManualBlindBarcodeParsingEventRequestFootPrintProcedure(decimal actualPackagedAmount, int actualPackagedPackId, string lotLookupCode,
            int warehouseId, int materialId, string vendorLotLookupCode, DateTime vendorLotManufactureDate, 
            DateTime vendorLotExpirationDate, int shipmentId, decimal netWeight, 
            decimal grossWeight, string serialLookupCode, string licensePlateLookupCode)
        {
            _barcodeReceivingFootPrintDbContext.Database
                .ExecuteSqlCommand("EXEC noram_reporting.ManualBlindBarcodeParsingEventRequest " +
                                   "@ActualPackagedAmount, @ActualPackagedPackId, @LotLookupCode, @WarehouseId, @MaterialId, @VendorLotLookupCode," +
                                   "@VendorLotManufactureDate, @VendorLotExpirationDate, @ShipmentId, @netWeight, @grossWeight, @serialLookupCode, @licensePlateLookupCode",
                    new SqlParameter("@ActualPackagedAmount", actualPackagedAmount),
                    new SqlParameter("@ActualPackagedPackId", actualPackagedPackId),
                    new SqlParameter("@LotLookupCode", lotLookupCode),
                    new SqlParameter("@WarehouseId", warehouseId),
                    new SqlParameter("@MaterialId", materialId),
                    new SqlParameter("@VendorLotLookupCode", vendorLotLookupCode),
                    new SqlParameter("@VendorLotManufactureDate", vendorLotManufactureDate),
                    new SqlParameter("@VendorLotExpirationDate", vendorLotExpirationDate),
                    new SqlParameter("@ShipmentId", shipmentId),
                    new SqlParameter("@netWeight", netWeight),
                    new SqlParameter("@grossWeight", grossWeight),
                    new SqlParameter("@serialLookupCode", serialLookupCode),
                    new SqlParameter("@licensePlateLookupCode", licensePlateLookupCode)
                    );
        }
    }
}

Вот тогда я вызываю этот метод для вставки в каждый параметр

private void SendStoredProcedureDataToFootPrint()
{
    var lotList = _connection.ParseLot();
    var netWeightList = _connection.ParseNetWeight();
    var grossWeightList = _connection.ParseGrossWeight();
    var serialNumberList = _connection.ParseSerialNumber();
    var material = _unitOfWork.Shipments.GetLastShipmentMaterialEntry();
    var scanCounts = _connection.CountReceivingBarcodeEntries();
    var packagingId = _unitOfWork.Materials.GetPackagingId();
    var warehouse = _unitOfWork.Warehouses.GetWarehouseIdQuery();
    var shipment = _unitOfWork.Shipments.GetLastShipmentIdEntry();
    var licensePlate = _unitOfWork.LicensePlates.GetLastCreatedLicensePlate();

    try
    {
        for (var i = 0; i < _connection.GetBarcodeList().Count ; i++)
        {

            _storedProcedureInsert.CallManualBlindBarcodeParsingEventRequestFootPrintProcedure(scanCounts, packagingId, lotList[i], warehouseId: warehouse, materialId: 5785,
                vendorLotLookupCode: lotList[i], vendorLotManufactureDate: DateTime.Now,
                vendorLotExpirationDate: DateTime.Now, shipmentId: shipment,
                netWeight: Convert.ToDecimal(netWeightList[i]) / 100,
                grossWeight: Convert.ToDecimal(grossWeightList[i]) / 100,
                serialLookupCode: serialNumberList[i], licensePlateLookupCode: licensePlate);
        }
    }
    catch (Exception exception)
    {
        MetroMessageBox.Show(null, exception.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        throw;
    }
}

Итак, как и ясказал, что это работает, если я вставлю 1 данные для каждого параметра, но если в массивах lotlist, netweightlist, grossweightlist и serialnumberlist содержится более 1 данных, они не будут отправлены в хранимую процедуру.

Таким образом, цель состоит в том, чтобы вставить эти данныеНеважно, есть много записей, которые мне нужно вставить, это может быть одна или несколько одновременно.

Не удалось найти хорошее решение по этому вопросу в других вопросах, таких как stackoverflow или google.

1 Ответ

1 голос
/ 16 марта 2019

Пожалуйста, используйте Табличные Значимые Параметры для обработки подобных сценариев. Но вы должны преобразовать свои данные в DataTable. Для каждого массива будет соответствующая таблица данных.

Я хотел бы дать вам идею.

  1. Преобразование каждого списка C # в DataTable.

    Конвертировать каждый массив (например, serialNumberList в DataTable.) (Если это просто примитивные данные, то будет соответствовать только один столбец, если это объект, а затем полная строка. В этом случае для каждой строки: каждая ячейка будет соответствовать данным, соответствующим C # элемент данных объекта.)

  2. Создать в SQL Server тип данных в разделе «Программируемость», который будет получать эти таблицы данных из вашего кода C #. Этот тип данных будет иметь точно такие же данные с тем же отдельным типом SQL, который был в структуре C #.

  3. Что бы вы ни делали внутри цикла (в отношении преобразования или выполнения некоторых математических операций, сделайте это в том же списке, прежде чем даже переходить в SQL. В конце концов, передайте данные в SQL, когда они уже обработаны).

  4. Перед передачей данных в SQL вы должны знать, что данные должны быть переданы как параметр с табличным значением. Поэтому его тип данных должен быть выбран как SQLDataType.Structured.

  5. Для каждого элемента данных, не включенного в список, не создавайте DataTable. Просто передайте его как есть, используя собственный тип данных SQL из .NET.

Дайте мне знать, если вы решите свою проблему таким образом. Я уверен, что это сработает. Более того, если вы хотите узнать, как передать сложную структуру / массив данных типа Simple Native или Object Array, обратитесь по следующей ссылке.

T-SQL - вставка данных в родительские и дочерние таблицы .

...