The following code gives me the results I need, but can anyone suggest how to write it better? I'm sure there's a more efficient way to do it.
Thanks.
private bool IsLocation(Guid _vID, Guid OrganisationId)
{
var vehicle = _vehilceRepository.GetSingle(c => c.vehicleId == _vID);
var clients = _clientRepository.GetList(c => c.OrganisationID == OrganisationId);
foreach (var client in clients)
{
var locations = _LocationRepository.GetList(c => c.ClientID == client.ClientID);
if (locations.Count > 0)
{
foreach (var location in locations)
{
if (location.LocationId == vehicle.LocationID)
{
return true;
}
}
}
}
return false;
}
var vehicle = _vehilceRepository.GetSingle(c => c.vehicleId == _vID);
var clients = _clientRepository.GetList(c => c.OrganisationID == OrganisationId);
return clients.SelectMany(client => _LocationRepository.GetList(
c => c.ClientID == client.ClientID))
.Any(location => location.LocationId == vehicle.LocationID);
?
Related
I have the following code..
var GetStock = db.tabStocks.Where(x => x.SourceDocRef == InvoiceNumber.Text);
List<tabStock> tbs = new List<tabStock>();
foreach (var Stk in GetStock)
{
switch (GetStock.Any(y => y.ProductSKU == Stk.ProductSKU && y.Id != Stk.Id))
{
case true:
if (!(tbs.AsEnumerable().Any(x => x.Id == Stk.Id))) {
tbs.Add(Stk);
}//tbs.AddRange(GetStock2.Where(g => g.ProductSKU == Stk.ProductSKU && g.Id != Stk.Id));
var GetOthers = GetStock.Where(x => x.Id != Stk.Id && x.ProductSKU == Stk.ProductSKU );
foreach (var Gt in GetOthers) {
if (!(tbs.AsEnumerable().Any(x => x.Id == Gt.Id))) {
tbs.Add(Gt);
}
} break;
}
}
//Group and Remove tbs
Literal1.Text += tbs.AsEnumerable().Count();
try
{
var GroupIt = tbs.GroupBy(x => x.ProductSKU ).AsEnumerable()
.Select(g => new tabStock
{
ProductName = g.FirstOrDefault().ProductName,
ProductSKU = g.FirstOrDefault().ProductSKU,
Qty = g.Sum(n => n.Qty).Value,
OutQty = g.Sum(n => n.Qty).Value,
Bal = (db.tabStocks.Any(x => x.ProductSKU == g.FirstOrDefault().ProductSKU && x.SourceDocRef != g.FirstOrDefault().SourceDocRef && x.Id < g.OrderBy(t => t.Id).FirstOrDefault().Id) ? db.tabStocks.Where(x => x.ProductSKU == g.FirstOrDefault().ProductSKU && x.SourceDocRef != g.FirstOrDefault().SourceDocRef && x.Id < g.OrderBy(t => t.Id).FirstOrDefault().Id).OrderByDescending(x => x.Id).FirstOrDefault().Bal - g.Sum(f => f.Qty).Value : (0 - g.Sum(f => f.Qty)).Value).Value,
TransactionRef = g.FirstOrDefault().TransactionRef,
CreatedBy = g.FirstOrDefault().CreatedBy,
CreationDate = g.FirstOrDefault().CreationDate,
SourceDocRef = g.FirstOrDefault().SourceDocRef,
InQty = 0,
transactionType = "Sale",
UnitCost = g.FirstOrDefault().UnitCost.Value,
Received = 0,
TotalValuation = 0,
});
foreach (var NewStk in GroupIt.AsEnumerable())
{
tabStock stk = new tabStock();
stk.ProductName = NewStk.ProductName;
stk.ProductSKU = NewStk.ProductSKU;
stk.Qty = NewStk.Qty;
stk.OutQty = NewStk.OutQty;
stk.Bal = NewStk.Bal;
stk.transactionType = NewStk.transactionType;
stk.TransactionRef = NewStk.TransactionRef;
stk.CreatedBy = NewStk.CreatedBy;
stk.CreationDate = NewStk.CreationDate;
stk.SourceDocRef = NewStk.SourceDocRef;
stk.InQty = NewStk.InQty;
stk.UnitCost = NewStk.UnitCost;
stk.Received = 0;
stk.TotalValuation = 0;
db.tabStocks.Add(stk);
}
foreach (var OldStk in tbs.AsEnumerable())
{
db.tabStocks.Remove(OldStk);
}
db.SaveChanges();
For some reason i have this error:
Unable to create a constant value of type
'Type'. Only primitive types or enumeration types are supported in this context
Can anyone help me point to what this could be. I have looked at a lot of others related, nothing seems to work.. toList(), AsEnumerable(). Where is my code wrong please.
What can I do to make this loop run faster?
private void accessVendorGridData()
{
try
{
foreach (var item in getAllVendorList)
{
item.CurrencyName = "USD";
// Fetch Addresses in Vendor Grid
var Addr = _vendorservice.GetAllVendorAdd().Where(x => x.vendorId == item.Id).ToList();
if (Addr.Count > 0)
{
item.VendorAddressLine = String.Format("{0}, {1}, {2}, {3}, {4}", Addr[0].Address, Addr[0].City, Addr[0].StateProvince, Addr[0].ZipPostalCode, Addr[0].CountryRegion);
}
// Fetch Payment terms in Vendor Grid
var paymentTerm = _vendorservice.GetAllPaymentTerms().Where(x => x.Id == item.PaymentTermId).ToList().SingleOrDefault();
if (paymentTerm != null)
{
item.paymenttermitem = paymentTerm.Name;
}
// Fetch Tax Scheme in Vendor Grid
var taxscheme = _vendorservice.GetAllTaxScheme().Where(x => x.Id == item.TaxschemeId).ToList().SingleOrDefault();
if (taxscheme != null)
{
item.TaxschemeName = taxscheme.TaxSchemaName;
}
}
}
catch (Exception ex)
{
_exLog.AddErrorLog(ex, "NewVendor, accessVendorGridData()");
ModernDialog.ShowMessage(ex.Message, "Error!", MessageBoxButton.OK);
}
}
What can I do to make this loop run faster? I tried Parallel.ForEach but lost in between. Can somebody help?
private void accessVendorGridData()
{
foreach (var item in getAllVendorList)
{
var Addr = _vendorservice.GetAllVendorAdd().Where(x => x.vendorId == item.Id).ToList();
var paymentTerm = _vendorservice.GetAllPaymentTerms().Where(x => x.Id == item.PaymentTermId).ToList().SingleOrDefault();
var taxscheme = _vendorservice.GetAllTaxScheme().Where(x => x.Id == item.TaxschemeId).ToList().SingleOrDefault();
}
}
Instead of querying at each iteration you can extract vendors, paymentTerms and allTaxSchemes from the loop as dictionaries:
private void accessVendorGridData() {
var vendors = _vendorservice
.GetAllVendorAdd()
.GroupBy(item => item.Id)
.ToDictionary(chunk => chunk.Key, chunk => chunk.ToList());
var paymentTerms = _vendorservice
.GetAllPaymentTerms()
.GroupBy(item => item.Id)
.ToDictionary(chunk => chunk.Key, chunk => chunk.SingleOrDefault());
var allTaxSchemes = _vendorservice
.GetAllTaxScheme()
.GroupBy(item => item.Id)
.ToDictionary(chunk => chunk.Key, chunk => chunk.SingleOrDefault());
foreach (var item in getAllVendorList) {
var Addr = vendors.TryGetValue(item.Id, out var addrs)
? addrs
: new List<Vendor>(); //TODO: put the right type instead of Vendor
var paymentTerm = paymentTerms.TryGetValue(item.PaymentTermId, out var term)
? term
: null;
var taxscheme = allTaxSchemes.TryGetValue(item.PaymentTermId, out var scheme)
? scheme
: null;
}
}
Your current code has
O(|getAllVendorList| * (|vendors| + |paymentTerms| + |allTaxSchemes|))
time complexity, this one has
O(|getAllVendorList| + |vendors| + |paymentTerms| + |allTaxSchemes|)
However, it's not a solution if _vendorservice.GetXXX() is a query to service, RDBMS etc. and you have to call it at each iteration (since data can be changed)
Hi Is there a more ellegant way of doing this must I do the loop is there like a range funciton I could just remove all the items found
Sorry I should have showing how my qry is being inserted.
Btw these are two different entities that I am removing from I hope you get the idea.
var qry = db.AssemblyListItems.AsNoTracking().Where(x =>
x.ProductionPlanID == (long)_currentPlan.ProductionPlan ).ToList();
var hasbeenAssembled = db.CompletedPrinteds.AsNoTracking().Where(x =>
x.ProductionPlanId == item.ProductionPlanID).ToList();
var hasbeenFound = db.CompletedPrinteds.AsNoTracking().Where(x =>
x.ProductionPlanId== item.ProductionPlanID).ToList();
foreach (var subitem in hasbeenAssembled )
{
if(item.ProductionPlanID ==subitem.ProductionPlanId && item.DocumentNo == subitem.DocumentNo && item.DocumentNo == subitem.DocumentNo && item.OutstandingToMake ==0)
{
qry.RemoveAll(x => x.ProductionPlanID == subitem.ProductionPlanId && x.DocumentNo == item.DocumentNo && x.ItemCode == subitem.StockCode && item.OutstandingToMake ==0);
}
}
public List<AssemblyListItems> RemoveDespatchedItems(List<AssemblyListItems> AssemblyItems)
{
foreach (AssemblyListItems item in AssemblyItems)
{
using (var db = new LiveEntities())
{
var hasNotBeenDespatched = db.PalletizedItems.Where(w => w.Despatched != "Not Despatched");
foreach (var subitem in hasNotBeenDespatched)
{
AssemblyItems.RemoveAll(x => x.ProductionPlanID == subitem.ProductionPlanID && x.DocumentNo == item.DocumentNo && x.ItemCode == subitem.StockCode);
}
}
}
return AssemblyItems;
}
I just need to remove the items from the first query hasNotBeenDespatched from the second query.As could be over 400 items i want it to be efficient as possible.
Edit 2
I am a we bit closer thanks buts its still not removing the items from the removedespatchitems from the assebmittems I do not no why
public List<AssemblyListItems> RemoveDespatchedItems(List<AssemblyListItems> AssemblyItems, Int64 ProductionPlanId)
{
using (var db = newLiveEntities())
{
List<PalletizedItems> removeDespatchItems = db.PalletizedItems.Where(w => w.Despatched != "Not Despatched" && w.ProductionPlanID == ProductionPlanId).ToList();
var itemsDocumentNo = db.PalletizedItems.Select(x => x.ProductionPlanItemID).ToList();
foreach (var subitem in removeDespatchItems) {
AssemblyItems.RemoveAll(x => x.ProductionPlanID == subitem.ProductionPlanID && itemsDocumentNo.Contains(x.ProductionPlanItemID) && x.ItemCode == subitem.StockCode && x.LineQuantity==x.AllocatedQuantity);
}
}
return AssemblyItems;
}
Not 100% I get exactly how it should be.
However in general you could use join that would result in it being done in the database. Something like this:
var remainingItems = (from ali in db.FUEL_AssemblyListItems
join completed in db.FuelCompletedPrinteds
on new { ali.ProductionPlanID, ali.DocumentNo, ali.ItemCode } equals new { completed.ProductionPlanID, completed.DocumentNo, completed.StockCode }
join dispatched in db.FUEL_PalletizedItems
on new { ali.ProductionPlanID, ali.DocumentNo, ali.ItemCode } equals new { dispatched.ProductionPlanID, dispatched.DocumentNo, dispatched.StockCode }
where (ali.ProductionPlanID == (long) _currentPlan.ProductionPlan
&& ali.DocumentNo == completed.DocumentNo
&& completed.OutstandingToMake == 0
&& dispatched.Despatched != "Not Despatched")
select ali).ToList();
Depending upon the records in the database the join might need to be a outer join which needs a slightly different syntax but hopefully you've got a starting point.
I have several foreach chained.
I would like to know if it is possible to do a linq synthesis of these foreach.
foreach(var item in parameter)
{
foreach (var worksheets in item.Item6.Worksheets)
{
var worksheetName = worksheets.Value.Name;
foreach (var dynamicRange in worksheets.Value.DynamicRanges)
{
var dynamicRangeRowStartIndex = dynamicRange.RowStartIndex;
var dynamicRangeColumnStartIndex = dynamicRange.ColumnStartIndex;
foreach (var node in dynamicRange.Nodes)
{
var nodeDirection = node.Direction;
foreach (var rule in node.Rules)
{
reportWorkbook.Worksheets.Values.First(c => c.Name == worksheetName).DynamicRanges.First(c => c.RowStartIndex == dynamicRangeRowStartIndex && c.ColumnStartIndex == dynamicRangeColumnStartIndex)
.NodeByDirection(nodeDirection).Rules[ruleCount].DefinitionRule.ContextItem = item.Item6.Worksheets.Values.First(c => c.Name == worksheetName).DynamicRanges.First(c => c.RowStartIndex == dynamicRangeRowStartIndex && c.ColumnStartIndex == dynamicRangeColumnStartIndex)
.NodeByDirection(nodeDirection).Rules[ruleCount].DefinitionRule.ContextItem;
ruleCount++;
}
ruleCount = 0;
}
}
}
}
Do you have any idea how to do this?
Thank you
how to simplify below code:
public List<Cwzz_CashFlowItem> AllDataPage(int start, int limit, out int total, string xmbmLike, string xmmcLike)
{
List<Cwzz_CashFlowItem> ll;
if (xmbmLike != "" && xmmcLike != "")
{
total = _ctx.Cwzz_CashFlowItem
.Where(v => v.CashFlowCode.Contains(xmbmLike))
.Count(v => v.CashFlowName.Contains(xmmcLike));
ll = _ctx.Cwzz_CashFlowItem
.Where(v => v.CashFlowCode.Contains(xmbmLike))
.Where(v => v.CashFlowName.Contains(xmmcLike))
.OrderBy(v => v.CashFlowCode).Skip(start).Take(limit).ToList();
}
else if (xmbmLike != "" && xmmcLike == "")
{
total = _ctx.Cwzz_CashFlowItem
.Count(v => v.CashFlowCode.Contains(xmbmLike));
ll = _ctx.Cwzz_CashFlowItem
.Where(v => v.CashFlowCode.Contains(xmbmLike))
.OrderBy(v => v.CashFlowCode).Skip(start).Take(limit).ToList();
}
else if (xmbmLike == "" && xmmcLike != "")
{
total = _ctx.Cwzz_CashFlowItem
.Count(v => v.CashFlowName.Contains(xmmcLike));
ll = _ctx.Cwzz_CashFlowItem
.Where(v => v.CashFlowName.Contains(xmmcLike))
.OrderBy(v => v.CashFlowCode).Skip(start).Take(limit).ToList();
}
else
{
total = _ctx.Cwzz_CashFlowItem.Count();
ll = _ctx.Cwzz_CashFlowItem
.OrderBy(v => v.CashFlowCode)
.Skip(start).Take(limit).ToList();
}
return ll;
}
if there are more conditions not two, the if-else will be more complicated, so how to simplify code above.
Linq expressions can be chained. Avoid premature coercion into a List<>.
public IQueryable<Cwzz_CashFlowItem> AllDataPage(...) {
IQueryable<Cwzz_CashFlowItem> ll = _ctx.Cwzz_CashFlowItem;
if (xmbmLike != "")
{
ll = ll.Where(v => v.CashFlowCode.Contains(xmbmLike));
}
if (xmcmLike != "")
{
ll = ll.Where(v => v.CashFlowCode.Contains(xmcmLike));
}
return ll.OrderBy(v => v.CashFlowCode).Skip(start).Take(limit);
}
I'll leave returning the out Count as an exercise.