Вход на сайт
Можно ли это сделать LINQом?
146 просмотров
Перейти к просмотру всей ветки
в ответ dymanoid 24.08.17 18:47
Проще, наверное, дать текущий код:
using System;using System.Data;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;using log4net;using ExceptionHandler;using Olympic.Misk.Range;using Olympic.Orders.DeliveryStatus;using Olympic.Orders.QtyDelivered;namespace Olympic.Orders.UnfinishedOrders{public static partial class TUnfinishedOrders{public partial class Table : Olympic.Shared.UnfinishedOrders.TUnfinishedOrders.Table{#region Loggingprivate static readonly ILog logger = LogManager.GetLogger(typeof(Table).Name);#endregion Logging#region Local Datastatic protected DataTable empty;#endregion#region Constructorpublic Table() : base() { }protected internal Table(DataTable pDt) : base(pDt) { }#endregion#region Methodsprotected override CareyGlass.AbstractBO.Row GetNewRow() { return new Row(); }protected override CareyGlass.AbstractBO.Subset GetEmptySubset() { return new Subset(); }// here passed a Batch rangespublic void Load(TRangeCollection pRanges){//batchRanges = pRanges;Olympic.Sql.TGetCurrentOrders sqlt = new Olympic.Sql.TGetCurrentOrders();sqlt.Ranges = pRanges;//sqlt.Stations = new TKnownStations();try{DataTable rawdata = DbExec.TExecFactory.LiProd.FillDataTable(sqlt);if (empty == null) empty = rawdata.Clone();rawdata.TableName = "DTBcdsToDo";int rowsCount = rawdata.Rows.Count;Table currentOrders = new Table(rawdata);dt = GetUnfinishedOrders(currentOrders);}catch (Exception ex){TExceptionHandler.Error(ex);}} // check config!!!private DataTable GetUnfinishedOrders(Table pCurrentOrders){Table unfinishedOrders = new Table(empty.Clone());TRange range = new TRange(pCurrentOrders.MinOrderNo, pCurrentOrders.MaxOrderNo);OrderRange = new TRangeCollection("DummyFieldName");OrderRange.Add(range);TDistinctOrders.Distinct distinctOrders = new TDistinctOrders.Distinct(pCurrentOrders);string orderList = distinctOrders.GetOrdersList();TDeliveryStatus.Table deliveryStatus = new TDeliveryStatus.Table();deliveryStatus.Load(OrderRange, orderList);TQtyDelivered.Table qtyDelivered = new TQtyDelivered.Table();qtyDelivered.Load(orderList);System.Diagnostics.Stopwatch stopwatch1 = System.Diagnostics.Stopwatch.StartNew();//var query1 = from current in pCurrent.Rows.Cast<DataRow>().Select(r => (Row)r)// join delivery in deliveryStatus.Cast<TDeliveryStatus.Row>() on current.OrderNo equals delivery.OrderNo// where delivery.DeliveryStatusS == TDeliveryStatus.NotDelivered// // || delivery.DeliveryStatusS == TDeliveryStatus.PartiallyDelivered// select current;var undeliveredAll = from current in pCurrentOrders.Cast<Row>().Select(r => r)join delivery in deliveryStatus.Cast<TDeliveryStatus.Row>() on current.OrderNo equals delivery.OrderNowhere delivery.DeliveryStatusS == TDeliveryStatus.NotDelivered// || delivery.DeliveryStatusS == TDeliveryStatus.PartiallyDeliveredorderby current.OrderNo, current.ItemNoselect current;var partlyAll = from current in pCurrentOrders.Cast<Row>().Select(r => r)join delivery in deliveryStatus.Cast<TDeliveryStatus.Row>() on current.OrderNo equals delivery.OrderNowhere delivery.DeliveryStatusS == TDeliveryStatus.PartiallyDeliveredorderby current.OrderNo, current.ItemNoselect current;var query3 = from undeliverd in partlyAlljoin quantity in qtyDelivered.Cast<TQtyDelivered.Row>()on new { undeliverd.OrderNo, undeliverd.ItemNo }equals new { quantity.OrderNo, quantity.ItemNo }orderby undeliverd.OrderNo, undeliverd.ItemNoselect new { undeliverd, quantity };int quantityCount = -1;int currentOrderNo = -1;int currentItemNo = -1;foreach (var pair in query3){if (pair.undeliverd.OrderNo != currentOrderNo|| pair.undeliverd.ItemNo != currentItemNo){currentOrderNo = pair.undeliverd.OrderNo;currentItemNo = pair.undeliverd.ItemNo;quantityCount = 0;//logger.InfoFormat("Order/item {0}/{1} required {2} not deliverd {3}, Restart counter", pair.undeliverd.OrderNo, pair.undeliverd.ItemNo, pair.quantity.QtyItem, pair.quantity.QtyCompNotDelivered);}if (++quantityCount <= pair.quantity.QtyCompNotDelivered){pair.undeliverd.DeliveryStatus = TDeliveryStatus.PartiallyDelivered;unfinishedOrders.ImportRow(pair.undeliverd);//logger.InfoFormat("Order/item {0}/{1} required {2} not deliverd {3}, added", pair.undeliverd.OrderNo, pair.undeliverd.ItemNo, pair.quantity.QtyItem, pair.quantity.QtyCompNotDelivered);}else{//skip this pair//logger.InfoFormat("Order/item {0}/{1} required {2} not deliverd {3}, skiped", pair.undeliverd.OrderNo, pair.undeliverd.ItemNo, pair.quantity.QtyItem, pair.quantity.QtyCompNotDelivered);}}foreach (Row urow in undeliveredAll){urow.DeliveryStatus = TDeliveryStatus.NotDelivered;unfinishedOrders.ImportRow(urow);}stopwatch1.Stop();System.Diagnostics.Debug.WriteLine("Selection for undelivered/partlidelivered took " + stopwatch1.Elapsed + "");System.Diagnostics.Debug.WriteLine("Rows selected: " + unfinishedOrders.dt.Rows.Count);//return unfinishedOrders.dt;return unfinishedOrders.dt.Select("", "orderNo,itemNo").CopyToDataTable();}#endregion#region Properties//public new Row FirstRow { get { return (Row)base.FirstRow; } }public TRangeCollection OrderRange { get; internal set; }#endregion#region Propeties Calculationpublic Decimal MinOrderNo { get { return Convert.ToDecimal(dt.Compute("MIN(orderNo)", "")); } }public Decimal MaxOrderNo { get { return Convert.ToDecimal(dt.Compute("MAX(orderNo)", "")); } }#endregion}}}
Меня интересует выполнение фильтрации в цикле foreach (var pair in query3) ЛИНКом.
Чтобы упростилось до уровня foreach (Row urow in undeliveredAll)
Mожно и так оставить - оно достаточно быстрое - 0.5 сек на 20К записей, но все же интересно - можно ли слепить такой фильтр v LINQ.