Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

​Можно ли это сделать LINQом?

25.08.17 10:31
Re: ​Можно ли это сделать LINQом?
 
Murr патриот
Murr
в ответ 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 Logging

private static readonly ILog logger = LogManager.GetLogger(typeof(Table).Name);

#endregion Logging

#region Local Data

static protected DataTable empty;

#endregion

#region Constructor

public Table() : base() { }
protected internal Table(DataTable pDt) : base(pDt) { }

#endregion

#region Methods

protected override CareyGlass.AbstractBO.Row GetNewRow() { return new Row(); }
protected override CareyGlass.AbstractBO.Subset GetEmptySubset() { return new Subset(); }

// here passed a Batch ranges
public 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.OrderNo
where delivery.DeliveryStatusS == TDeliveryStatus.NotDelivered
// || delivery.DeliveryStatusS == TDeliveryStatus.PartiallyDelivered
orderby current.OrderNo, current.ItemNo
select current;

var partlyAll = from current in pCurrentOrders.Cast<Row>().Select(r => r)
join delivery in deliveryStatus.Cast<TDeliveryStatus.Row>() on current.OrderNo equals delivery.OrderNo
where delivery.DeliveryStatusS == TDeliveryStatus.PartiallyDelivered
orderby current.OrderNo, current.ItemNo
select current;

var query3 = from undeliverd in partlyAll
join quantity in qtyDelivered.Cast<TQtyDelivered.Row>()
on new { undeliverd.OrderNo, undeliverd.ItemNo }
equals new { quantity.OrderNo, quantity.ItemNo }
orderby undeliverd.OrderNo, undeliverd.ItemNo
select 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 Calculation

public 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.

 

Перейти на