Использование виртуальной коллекции в C# для повышения эффективности кода - PullRequest
0 голосов
/ 27 марта 2020

Здравствуйте, у меня есть модель, которая выглядит следующим образом:

  public class Site
    {
        public int ID { get; set; }

        public string Name { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string Province { get; set; }
        public string PostalCode { get; set; }

        public virtual ICollection<OffSiteItemDetails> ItemDetails { get; private set; }
        public virtual ICollection<SalesOrder> soDetails { get; private set; }
        public virtual ICollection<SODetails> SODDetails { get; private set; }

        public string IncomingTotalOSI(Site s)
        {
            PIC_Program_1_0Context db = new PIC_Program_1_0Context();
            float? partCost = 0;
            float? componentCost = 0;
            float? itemCost = 0;
            float? incomingCost = 0;
            List<OffSiteItemDetails> d = ItemDetails.Where(x => x.siteID == s.ID).ToList();


            var less30days = DateTime.Now.AddDays(-30);
            //List<SalesOrder> so = soDetails.Where(x => x.OrderType == SOType.OffSiteInventory).Where(x => x.DateCreated > less30days).ToList();
            List<SalesOrder> so = db.SalesOrders.Where(x => x.OrderType == SOType.OffSiteInventory).Where(x => x.DateCreated > less30days).ToList();
            List<SODetails> sod = db.SODetails.Where(x => x.SiteID == s.ID).ToList();

       foreach (var order in so)
        {

            foreach (var details in sod)
            {

                if (order.ID == details.SalesOrderID)
                {

                    if (details.PartID != null){
                        partCost += details.part_qty * db.Parts.Where(x => x.ID == details.PartID).FirstOrDefault().AveCostPerUnit;
                    }
                    else if (details.ComponentID != null){
                        componentCost += details.comp_qty * db.Components.Where(x => x.ID == details.ComponentID).FirstOrDefault().AveCostPerUnit;
                    }
                    else{
                        itemCost += details.item_qty * db.Items.Where(x => x.ID == details.ItemID).FirstOrDefault().CostPerUnit;
                    }
                }

            }
        }
        incomingCost = partCost + componentCost + itemCost;

            string cost = String.Format("{0:C}", incomingCost);

            return cost;
        }
  }

Но это неэффективно, поскольку она повторяется по одному и тому же набору данных несколько раз. И чем больше заказов будет добавлено, тем медленнее станет программа. Я все еще изучаю MVC и изучаю виртуальные коллекции, но я все еще не понимаю, как я могу использовать его в этом сценарии для повышения эффективности программы

1 Ответ

0 голосов
/ 29 марта 2020

Для начала я бы предложил удалить .ToList() из этой строки:

List sod = db.SODetails.Where(x => x.SiteID == s.ID).ToList();

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

Затем измените следующую строку:

foreach (var details in sod)

Кому:

foreach (var details in db.SODetails .Where(x => x.SiteID == s.ID && details.SalesOrderID == order.ID))

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

Вы также можете избавиться от оператора if () в самом внутреннем l oop и просто поместить свое условие в Linq, чтобы ограничить то, что зациклено. Это также может улучшить производительность:

foreach (var details in sod.Where(detail => detail.SalesOrderID == order.ID)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...