Скопируйте информацию о транспортном средстве из списка JSON в реляционную базу данных

Я ищу предложение, чтобы мой цикл for выполнялся быстрее. Около 2000 строк данных. Для выполнения кода ниже требуется много времени. До сих пор я следил за различными ответами на переполнение стека. Например, уменьшение количества запросов к базе данных и использование массовой вставки для повышения производительности EF. Он просто немного улучшился.

List<VehicleApplication> vehicleApplicationList = new List<VehicleApplication>();
List<ProductVehicleApplication> productVehicleApplicationList = new List<ProductVehicleApplication>();

if (inventoryjson["InventoryItems"][0]["VehicleApplications"] != null)
{
    for (int i = 0; i < inventoryjson["InventoryItems"][0]["VehicleApplications"].Count(); i++)
    {
        //database vehDb = new database();
        VehicleApplication vehicleApplication = new VehicleApplication();
        vehicleApplication.CategoryName = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["CategoryName"].ToString();
        vehicleApplication.MakeName = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["MakeName"].ToString();
        vehicleApplication.MfrLabel = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["MfrLabel"].ToString();
        vehicleApplication.ModelName = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["ModelName"].ToString();
        vehicleApplication.Note = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["Note"].ToString();
        vehicleApplication.PartTypeName = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["PartTypeName"].ToString();
        vehicleApplication.PositionName = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["PositionName"].ToString();
        vehicleApplication.Qty = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["Qty"].ToString();
        vehicleApplication.SubCategoryName = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["SubCategoryName"].ToString();
        vehicleApplication.YearID = inventoryjson["InventoryItems"][0]["VehicleApplications"][i]["YearID"].ToString();

        var existingVehicleApplication = dbVehiclesList.Where(x => x.MakeName == vehicleApplication.MakeName && x.ModelName == vehicleApplication.ModelName
            && x.CategoryName == vehicleApplication.CategoryName
            && x.MfrLabel == vehicleApplication.MfrLabel
            && x.PartTypeName == vehicleApplication.PartTypeName
            && x.PositionName == vehicleApplication.PositionName
            && x.Qty == vehicleApplication.Qty
            && x.YearID == vehicleApplication.YearID
            && x.SubCategoryName == vehicleApplication.SubCategoryName
            ).SingleOrDefault();

        if (existingVehicleApplication == null && vehicleApplicationList.Any(x => x.MakeName == vehicleApplication.MakeName && x.ModelName == vehicleApplication.ModelName && x.CategoryName == vehicleApplication.CategoryName && x.MfrLabel == vehicleApplication.MfrLabel && x.PartTypeName == vehicleApplication.PartTypeName && x.PositionName == vehicleApplication.PositionName && x.Qty == vehicleApplication.Qty && x.YearID == vehicleApplication.YearID && x.SubCategoryName == vehicleApplication.SubCategoryName) == false)
        {
            vehicleApplicationList.Add(vehicleApplication);
        }
        else
        {
            vehicleApplication = dbObj.VehicleApplication.SingleOrDefault(
            x => x.MakeName == vehicleApplication.MakeName
            && x.ModelName == vehicleApplication.ModelName
            && x.CategoryName == vehicleApplication.CategoryName
            && x.MfrLabel == vehicleApplication.MfrLabel
            && x.PartTypeName == vehicleApplication.PartTypeName
            && x.PositionName == vehicleApplication.PositionName
            && x.Qty == vehicleApplication.Qty
            && x.SubCategoryName == vehicleApplication.SubCategoryName
            && x.YearID == vehicleApplication.YearID);
        }

        ProductVehicleApplication productVehicleApplication = new ProductVehicleApplication();
        productVehicleApplication.Product = dbObj.Product.Single(x => x.Id == product.Id);
        productVehicleApplication.VehicleApplication = vehicleApplication;
        productVehicleApplicationList.Add(productVehicleApplication);
    }
}

dbObj.BulkInsert(productVehicleApplicationList);
dbObj.BulkInsert(vehicleApplicationList);
dbObj.SaveChanges();

ОБНОВЛЕНИЕ :: 1 Из комментариев я пробовал следовать. Но это все равно медленно.

HashSet<VehicleApplication> vehicleApplicationList = new HashSet<VehicleApplication>();
                List<ProductVehicleApplication> productVehicleApplicationList = new List<ProductVehicleApplication>();
                if (jsonProduct["VehicleApplications"] != null)
                {
                 for (int i = 0; i < jsonProduct["VehicleApplications"].Count(); i++){
                            var vehicleApp = jsonProduct["VehicleApplications"][i];

                            VehicleApplication vehicleApplication = new VehicleApplication();
                            vehicleApplication.CategoryName = vehicleApp["CategoryName"].ToString();
                            vehicleApplication.MakeName = vehicleApp["MakeName"].ToString();
                            vehicleApplication.MfrLabel = vehicleApp["MfrLabel"].ToString();
                            vehicleApplication.ModelName = vehicleApp["ModelName"].ToString();
                            vehicleApplication.Note = vehicleApp["Note"].ToString();
                            vehicleApplication.PartTypeName = vehicleApp["PartTypeName"].ToString();
                            vehicleApplication.PositionName = vehicleApp["PositionName"].ToString();
                            vehicleApplication.Qty = vehicleApp["Qty"].ToString();
                            vehicleApplication.SubCategoryName = vehicleApp["SubCategoryName"].ToString();
                            vehicleApplication.YearID = vehicleApp["YearID"].ToString();


                            var existingVehicleApplication = dbVehiclesList.Where(x => x.MakeName == vehicleApplication.MakeName && x.ModelName == vehicleApplication.ModelName 
                                && x.CategoryName == vehicleApplication.CategoryName
                                && x.MfrLabel == vehicleApplication.MfrLabel
                                && x.PartTypeName == vehicleApplication.PartTypeName
                                && x.PositionName == vehicleApplication.PositionName
                                && x.Qty == vehicleApplication.Qty
                                && x.YearID == vehicleApplication.YearID
                                && x.SubCategoryName == vehicleApplication.SubCategoryName
                                ).SingleOrDefault(); 
                                
                    

                            if (existingVehicleApplication == null && vehicleApplicationList.Any(x => x.MakeName == vehicleApplication.MakeName && x.ModelName == vehicleApplication.ModelName && x.CategoryName == vehicleApplication.CategoryName && x.MfrLabel == vehicleApplication.MfrLabel && x.PartTypeName == vehicleApplication.PartTypeName && x.PositionName == vehicleApplication.PositionName && x.Qty == vehicleApplication.Qty && x.YearID == vehicleApplication.YearID && x.SubCategoryName == vehicleApplication.SubCategoryName) == false)
                            {
                                vehicleApplicationList.Add(vehicleApplication);
                            }
                            else
                            {
                                vehicleApplication = existingVehicleApplication;
                                //vehicleApplication = dbVehiclesList.SingleOrDefault(
                                //x => x.MakeName == vehicleApplication.MakeName
                                //&& x.ModelName == vehicleApplication.ModelName
                                //&& x.CategoryName == vehicleApplication.CategoryName
                                //&& x.MfrLabel == vehicleApplication.MfrLabel
                                //&& x.PartTypeName == vehicleApplication.PartTypeName
                                //&& x.PositionName == vehicleApplication.PositionName
                                //&& x.Qty == vehicleApplication.Qty
                                //&& x.SubCategoryName == vehicleApplication.SubCategoryName
                                //&& x.YearID == vehicleApplication.YearID);

                            }

                            ProductVehicleApplication productVehicleApplication = new ProductVehicleApplication();
                            productVehicleApplication.Product = dbProductList.Single(x=>x.Id==product.Id);
                            productVehicleApplication.VehicleApplication = vehicleApplication;


                            productVehicleApplicationList.Add(productVehicleApplication);
                        }
                    }

                    dbObj.BulkInsert(productVehicleApplicationList);
                    dbObj.BulkInsert(vehicleApplicationList);
                    dbObj.SaveChanges();
```

1 ответ
1

jsonProduct["VehicleApplications"].Count() должен находиться за пределами итерации, в противном случае он будет выполняться на каждой итерации, что повлияет на производительность. Итак, вам следует сделать:

var count = jsonProduct["VehicleApplications"].Count();

for (int i = 0; i < count; i++)
{
    var vehicleApp = jsonProduct["VehicleApplications"][i];
    ///...... etc.
}

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

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

попробуйте эту версию и посмотрите, как она работает:

var vehicleApplications = jsonProduct["VehicleApplications"]; 

if(vehicleApplications != null)
{
    HashSet<VehicleApplication> vehicleApplicationHashSet = new HashSet<VehicleApplication>();
    
    List<ProductVehicleApplication> productVehicleApplicationList = new List<ProductVehicleApplication>();

    var count = vehicleApplications.Count();

    for (int i = 0; i < count; i++)
    {
        var vehicleApp = jsonProduct["VehicleApplications"][i];

        VehicleApplication vehicleApplication = new VehicleApplication
        {
            CategoryName = vehicleApp["CategoryName"].ToString(),
            MakeName = vehicleApp["MakeName"].ToString(),
            MfrLabel = vehicleApp["MfrLabel"].ToString(),
            ModelName = vehicleApp["ModelName"].ToString(),
            Note = vehicleApp["Note"].ToString(),
            PartTypeName = vehicleApp["PartTypeName"].ToString(),
            PositionName = vehicleApp["PositionName"].ToString(),
            Qty = vehicleApp["Qty"].ToString(),
            SubCategoryName = vehicleApp["SubCategoryName"].ToString(),
            YearID = vehicleApp["YearID"].ToString()
        };
        
        var existingVehicleApplication = dbVehiclesList.FirstOrDefault(x =>
               x.MakeName == vehicleApplication.MakeName 
            && x.ModelName == vehicleApplication.ModelName 
            && x.CategoryName == vehicleApplication.CategoryName
            && x.MfrLabel == vehicleApplication.MfrLabel
            && x.PartTypeName == vehicleApplication.PartTypeName
            && x.PositionName == vehicleApplication.PositionName
            && x.Qty == vehicleApplication.Qty
            && x.YearID == vehicleApplication.YearID
            && x.SubCategoryName == vehicleApplication.SubCategoryName); 
        
        if(existingVehicleApplication != null)
        {
            vehicleApplication = existingVehicleApplication;
        }
        else
        {
            // if the vehicleApp is already in the hashset, then it'll not be added.
            vehicleApplicationHashSet.Add(vehicleApplication);
        }
        
        ProductVehicleApplication productVehicleApplication = new ProductVehicleApplication
        {
            Product = dbProductList.FirstOrDefault(x=>x.Id==product.Id),
            VehicleApplication = vehicleApplication
        };
        
        productVehicleApplicationList.Add(productVehicleApplication);
    }

    dbObj.BulkInsert(productVehicleApplicationList);
    dbObj.BulkInsert(vehicleApplicationList);
    dbObj.SaveChanges();
}

  • Это помогает мне немного улучшить, но var existingVehicleApplication = dbVehiclesList.FirstOrDefault Запрос к базе данных, поскольку dbVehiclesList — это AsEnumerable dbProductList.FirstOrDefault в том же случае. Возможно ли, что я получу данные из этих таблиц в очень быструю переменную, поэтому мне не нужно запрашивать db?

    — Джаскаран Сингх

  • 2

    @JaskaranSingh, какой ORM вы используете? поскольку фреймворк сущностей не нужно преобразовывать как AsEnumerable ..

    — iSR5


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *