I have two tables: Items and Colors. They have a many to many relation. In a CheckBoxList that displays colors, I want to check those that are associated to the item shown.
using (var db = new ProwebModel.Entities())
{
var colors = db.Colors;
foreach (ListItem color in ((CheckBoxList)(fv.FindControl("cblColors"))).Items)
{
var itemId = Convert.ToInt32(Request.QueryString["id"]);
var colorNumber = Convert.ToInt32(color.Value);
color.Selected = colors.Where(t => t.ColorNumber == colorNumber).First().Items.Where(t => t.ItemId == itemId).Count() > 0;
}
}
This works fine, but I was wondering about this line :
color.Selected = colors.Where(t => t.ColorNumber == colorNumber).First().Items.Where(t => t.ItemId == itemId).Count() > 0;
Is there any better way to check if the association exist?
Thank you!
EDIT
I chaged my code to something better.. I think. Is there still a better way to do this?
using (var db = new ProwebModel.Entities())
{
var itemId = Convert.ToInt32(Request.QueryString["id"]);
var ItemColors = db.Items.First(t => t.ItemId == itemId).Colors.ToList();
foreach (ListItem color in ((CheckBoxList)(fv.FindControl("cblColors"))).Items)
{
var colorNumber = Convert.ToInt32(color.Value);
color.Selected = ItemColors.Where(t => t.ColorNumber == colorNumber).Count() > 0;
}
}
Many thanks!
Code update
using (var db = new ProwebModel.Entities())
{
var itemId = Convert.ToInt32(Request.QueryString["id"]);
var ItemColors = db.Items.First(t => t.ItemId == itemId).Colors.ToList();
foreach (ListItem color in ((CheckBoxList)(fv.FindControl("cblColors"))).Items)
{
var colorNumber = Convert.ToInt32(color.Value);
color.Selected = ItemColors.Any(t => t.ColorNumber == colorNumber);
}
}
The line could at least be rewritten as :
color.Selected = colors.First(t => t.ColorNumber == colorNumber).Items.Any(t => t.ItemId == itemId);
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.
This question is propably more a concept question, but I'm stuck here logically.
I'm using LiveChart for WPF and I try to build a simple CartesianChart dynamically.
I load my Data from a CSV into a List, I'm counting how many times each datapair is in that file and add the amount. The result from this Linq request looks like this:
[0] { Dates = "20191123", Rank = "1st", Amount = 1 } <Anonymous Type>
I go through this result to pick me each date individually for the Lables of my CartesianChart
Now I would like to add my result Data into the CartesianChart for that I need a SeriesCollection mine looks like this:
SeriesCollection = new SeriesCollection
{
new LineSeries
{
Title = "1st",
Values = new ChartValues<int> {}
},
new LineSeries
{
Title = "2nd",
Values = new ChartValues<int> {}
},
new LineSeries
{
Title = "3rd",
Values = new ChartValues<int> {}
}
}
But when I go through my data on some dates I dont have for example first place, so I need a 0 amount value for this day. I'm struggeling to add this to my data.
Here is pretty much the whole code block im experimenting with, that also why it looks a little messy.
var data = File.ReadAllLines(FilePathes.resultPath).ToList();
var rankHistoryList = new List<RankHistory>();
foreach (var line in data)
{
rankHistoryList.Add(RankHistory.parse(line));
};
var result = rankHistoryList.GroupBy(x => new { x.Dates, x.Rank })
.Select(g => new { g.Key.Dates, g.Key.Rank, Amount = g.Count() })
.ToList();
var dates = new List<string>();
foreach (var entry in result)
{
dates.Add(entry.Dates);
}
var singleDates = dates.GroupBy(x => x).Select(grp => grp.First()).ToArray();
foreach (var day in singleDates) {
foreach (var entry in result) {
if (entry.Rank == "1st" && day == entry.Dates)
{
SeriesCollection[0].Values.Add(entry.Amount);
}
else if (entry.Rank != "1st" && day == entry.Dates)
{ SeriesCollection[0].Values.Add(0); }
}
}
I think my answer is the most complicated but at least it works:
var allRanks = new List<string>
{
"1st"
,"2nd"
,"3rd"
};
foreach (var entry in result)
{
dates.Add(entry.Dates);
}
var singleDates = dates.GroupBy(x => x).Select(grp => grp.First()).ToArray();
Labels = singleDates;
foreach (var ran in allRanks)
{
foreach (var day in singleDates)
{
if (ran == "1st")
{
if (result.Exists(x => x.Dates == day && x.Rank == ran) == true)
{
SeriesCollection[0].Values.Add(result.Where(w => w.Dates == day && w.Rank == ran).Select(x => x.Amount).First());
}
else SeriesCollection[0].Values.Add(0);
}
if (ran == "2nd")
{
if (result.Exists(x => x.Dates == day && x.Rank == ran) == true)
{
SeriesCollection[1].Values.Add(result.Where(w => w.Dates == day && w.Rank == ran).Select(x => x.Amount).First());
}
else SeriesCollection[1].Values.Add(0);
}
if (ran == "3rd")
{
if (result.Exists(x => x.Dates == day && x.Rank == ran) == true)
{
SeriesCollection[2].Values.Add(result.Where(w => w.Dates == day && w.Rank == ran).Select(x => x.Amount).First());
}
else SeriesCollection[2].Values.Add(0);
}
}
}
One of my function in C# required me to filter some value.So, I try it by using a lot of loop in it. It works but doesn't look like effecient.Any idea on how to convert code below to LinQ?
Any help is appreciated.
var object1 = JsonConvert.DeserializeObject<List<string>>(object1json);
foreach (var item1 in table1)
{
if (item1.Code == InputCode)
{
for (int i = 0; i < object1.Count(); i++)
{
tempData temp = new tempData();
foreach (var item2 in item1.List)
{
if (item2.Code == object1[i])
{
temp.Code = item2.Code;
temp.Description = item2.Description;
}
}
if(temp.Code != null || temp.Description != null)
final.Add(temp);
}
}
}
If you want your code to be more efficient, as pointed out in the comments, converting it to Linq isn't really going to help. It's still the same logic, just written in a different way. If you're going for readability, it can be improved with just a few changes:
foreach (var item1 in table1.Where(i => i.Code == InputCode))
{
foreach (var code in object)
{
// This could be SingleOrDefault, I don't know if you have duplicates in the list or not
var item2 = item1.List.LastOrDefault(i => i.Code == code);
if(item2 != null)
{
final.Add(new tempData
{
Code = item2.Code,
Description = item2.Description,
});
}
}
}
If you convert the whole thing to Linq:
var final = table1.Where(i => i.Code == InputCode)
.SelectMany(item1 => object.Select(code => item1.List.LastOrDefault(i => i.Code == code))
.Where(item2 => item2 != null)
.Select(item2 => new tempData
{
Code = item2.Code,
Description = item2.Description,
})
.ToList();
Personally, I prefer the first option, as it's a bit easier to read.
I guess what you post is sample code instead of actual code otherwise it would be better to avoid keyword like object in C#. Anyway,
var final = table1.Where(item1 => item1.Code == InputCode)
.SelectMany(item1 => item1.List)
.Where(item2 => #object.Contains(item2.Code))
.Where(temp => temp.Code != null || temp.Description != null)
.Select(item2 => new tempData()
{
Code = item2.Code,
Description = item2.Description
});
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
private static Game[] getMostPlayedGamesDo(int Fetch, int CategoryID)
{
Game[] r;
using (MainContext db = new MainContext())
{
if (CategoryID == 0)
{
var q = db.tblArcadeGames.OrderByDescending(c => c.Plays).Take(Fetch);
r = new Game[q.Count()];
int i = 0;
foreach (var g in q)
{
r[i] = new Game(g);
i++;
}
}
else
{
var q = db.tblArcadeGames.Where(c=>c.CategoryID == CategoryID).OrderByDescending(c => c.Plays).Take(Fetch);
r = new Game[q.Count()];
int i = 0;
foreach (var g in q)
{
r[i] = new Game(g);
i++;
}
}
}
return r;
}
I can't seem to define q outside the scope of the if, and I can't insert the returned values to the array outside the scope of the if! Not sure how to remove repeating code in this simple instance?
It's not clear what the type of q is -- but deducing from your usage:
db.tblArcadeGames.OrderByDescending(...)
Presumably it's an entity class from Linq-To-Sql or Entity Framework. In that case, you do have a concrete entity defined, presumably named tblArcadeGame. Therefore, move q out of the scope by not using var:
IQueryable<tblArcadeGame> q;
if (CategoryID == 0)
{
q = db.tblArcadeGames.OrderByDescending(c => c.Plays).Take(Fetch);
}
else
{
q = db.tblArcadeGames.Where(c=>c.CategoryID == CategoryID).OrderByDescending(c => c.Plays).Take(Fetch);
}
r = new Game[q.Count()];
int i = 0;
foreach (var g in q)
{
r[i] = new Game(g);
i++;
}
As you can see, the repeated code is now seen only once.
P.S. Tools like ReSharper are fantastic for this sort of thing. Using it, with one keystroke you can toggle between the var version and that using explicitly named types.
You should really just explicitly type q. But this may let you get away without it (ternary operator will enforce it for you).
var q = CategoryID == 0 ? db.tblArcadeGames.OrderByDescending(c => c.Plays).Take(Fetch)
: db.tblArcadeGames.Where(c=>c.CategoryID == CategoryID).OrderByDescending(c => c.Plays).Take(Fetch);
r = new Game[q.Count()];
int i = 0;
foreach (var g in q)
{
r[i] = new Game(g);
i++;
}
I assume q is type IQueryable.
private static Game[] getMostPlayedGamesDo(int Fetch, int CategoryID)
{
var q = db.tblArcadeGames;
if (CategoryID != 0)
{
q = q.Where(c => c.CategoryID == CategoryID);
}
q = q.OrderByDescending(c => c.Plays).Take(Fetch);
return q.Select(g => new Game(g)).ToArray();
}
List<tblArcadeGame> q;
/* object q; */
if (CategoryID == 0)
{
q = db.tblArcadeGames.OrderByDescending(c => c.Plays).Take(Fetch).ToList();
}
else
{
q = db.tblArcadeGames.Where(c=>c.CategoryID == CategoryID).OrderByDescending(c => c.Plays).Take(Fetch).ToList();
}
r = new Game[q.Count()];
int i = 0;
foreach (var g in q)
{
r[i] = new Game(g);
i++;
}
I'll assume q is List<tblArcadeGame>