var totalDistributed = db.Distributions
.Select(m => m.Product.ProductName == (string)productNameComboBox.SelectedItem).Any()
? db.Distributions.Sum(m => m.Piece) : 0;
var totalStock = db.StockIns
.Select(m => m.Product.ProductName == (string)productNameComboBox.SelectedItem)
.Any() ? db.StockIns.Sum(m => m.Piece) : 0;
Using this code, I get the sum of all values, but I want to get sum of specific values through productId using a linq query. productId comes from productNameComboBox.
You can try Where filter function instead of Select if Where filter function does not find any matches, Sum will return 0.
var totalDistributed = db.Distributions
.Where(m => m.Product.ProductName == (string)productNameComboBox.SelectedItem).Sum(m => m.Piece);
var totalStock = db.StockIns
.Where(m => m.Product.ProductName == (string)productNameComboBox.SelectedItem).Sum(m => m.Piece);
Related
I have a LINQ query which has three Where clauses. In each Where clause I am looking up the same set of items in order to compare values:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Where(x => level1Category == 0 || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Contains(level1Category))
.Where(x => !level2Categories.Any() || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Intersect(level2Categories.AsEnumerable()).Any())
.Where(x => !level3Categories.Any() || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Intersect(level3Categories.AsEnumerable()).Any());
Is there a way I can get the value of UmbracoAlias.Items.Categories once and store that value to be used in the other where clauses without causing the GetPropertyValue method to execute more than once?
You can pair up each item with category IDs, like this:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Select(c => new {
Child = c
, CategoryIds = c
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id)
.ToList()
})
.Where(x => level1Category == 0 || x.CategoryIds.Contains(level1Category))
.Where(x => !level2Categories.Any() || x.CategoryIds.Intersect(level2Categories.AsEnumerable()).Any())
.Where(x => !level3Categories.Any() || x.CategoryIds.Intersect(level3Categories.AsEnumerable()).Any())
.Select(x => x.Child);
This does the filtering on children paired up with their category IDs, and then keeps only the Child object in the final projection.
You could further simplify this by combining all three Where clauses:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Where(c => {
var categoryIds = c
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id)
.ToList();
if (level1Category != 0 && !categoryIds.Contains(level1Category)) {
return false;
}
if (level2Categories.Any() && !categoryIds.Intersect(level2Categories.AsEnumerable()).Any()) {
return false;
}
if (level3Categories.Any() && !categoryIds.Intersect(level3Categories.AsEnumerable()).Any()) {
return false;
}
return true;
});
This question already has answers here:
LINQ equal instead of Contains
(3 answers)
Closed 5 years ago.
I need to use Equals method or something similar instead of using Contains method because i want to search in database for the exact values in selectedDeviceTypeIDs array not any of it.
IEnumerable<Guid> selectedDeviceTypeIDs = DeviceTypeIDs
.Split(',')
.Select( Guid.Parse )
.AsEnumerable();
query = query
.Where( j =>
j.HospitalDepartments.Any( jj =>
jj.Units.Any( m =>
m.Devices.Any( w =>
selectedDeviceTypeIDs.Contains( w.DeviceTypeID )
)
)
)
);
Here is my full code
public HttpResponseMessage GetAvailableHospitalsByAjax(System.Guid? DirectorateOfHealthID = null, System.Guid? UnitTypeID = null, string DeviceTypeIDs = null)
{
Context db = new Context();
var query = db.Hospitals.AsQueryable();
if (DeviceTypeIDs != null)
{
IEnumerable<Guid> selectedDeviceTypeIDs = DeviceTypeIDs.Split(',').Select(Guid.Parse).AsEnumerable();
query = query.Where(j => j.HospitalDepartments.Any(jj => jj.Units.Any(m => m.Devices.Any(w => selectedDeviceTypeIDs.Contains(w.DeviceTypeID)))));
}
if (UnitTypeID != null)
{
query = query.Where(j => j.HospitalDepartments.Any(www => www.Units.Any(u => u.UnitTypeID == UnitTypeID)));
}
if (DirectorateOfHealthID != null)
{
query = query.Where(h => h.DirectorateHealthID == DirectorateOfHealthID);
}
query = query.Where(j => j.HospitalDepartments.Any(u => u.Units.Any(d => d.Devices.Any(s => s.Status == Enums.DeviceStatus.Free)))
&& j.HospitalDepartments.Any(hd => hd.Units.Any(u => u.Beds.Any(b => b.Status == Enums.BedStatus.Free))));
var list = query.ToList();
return Request.CreateResponse(HttpStatusCode.OK, list);
}
Your problem is not Contains() but with the Any() method used in your query which will return true immediately after it finds a device whose DeviceTypeID is in the provided selectedDeviceTypeIDs list.
If you need to check if all the devices of a unit match all the items in the list, you could use:
query = query
.Where(j =>
j.HospitalDepartments.Any(jj =>
jj.Units.Any(m =>
m.Devices.All(
w => selectedDeviceTypeIDs.Contains(w.DeviceTypeID))
&&
selectedDeviceTypeIDs.All(
g => m.Devices.Select(d => d.DeviceTypeID).Contains(g))
)
)
);
Note that if you have duplicate items in the selectedDeviceTypeIDs but not in the Devices of the Unit, it will still return true.
I'm trying to count the Total amount of Weight in a certain column.
I've tried the following coding, but I only seem to get the first row's value and not the rest.
int QuoteId = (from x in db.Quotes where x.Id != null orderby x.Id descending select x.Id).Take(1).SingleOrDefault();
var item = db.QuoteItems.Where(x => x.QuoteId == QuoteId).First();
QuoteItemSectionGroup quoteItemList = new QuoteItemSectionGroup();
foreach (var quoteItem in db.QuoteItemSectionGroups.Where(x => x.QuoteItemId == item.Id).ToList())
{
var total = new QuoteItemSectionGroup
{
Weight = quoteItem.Weight
};
quoteItemList.Weight = total.Weight;
}
So my question is: How can I count the total amount of the Weight column in my table?
You obviously want to add the current number to the Weigth you already obtained, don´t you? Furtheremore you won´t need to create a new instance of QuoteItemSectionGroup only for the sake of setting its Weight-property temporarily.
foreach (var quoteItem in db.QuoteItemSectionGroups.Where(x => x.QuoteItemId == item.Id).ToList())
{
quoteItemList.Weight += quoteItem.Weight; // pay attention on the + before the equality-character
}
The += operator in x += 1 is simply a shortcut for x = x + 1.
Or even simpler using Linq Sum-method
var totalWeight = db.QuoteItemSectionGroups
.Where(x => x.QuoteItemId == item.Id)
.Sum(x => x.Weight);
EDIT: Furthermore you can simplify your code a bit so it finally becomes this:
var item = db.Quotes.Where(x => x.Id != null)
.OrderByDescending(x => x.Id)
.FirstOrDefault();
var totalWeight = db.QuoteItemSectionGroups
.Where(x => x.QuoteItemId == item.Id)
.Sum(x => x.Weight);
I have a list of strings which contain X in them. I want to select list(s) with the minimum count of X in them. For example:
CountMin("AXBXX", "AAX") will return AAX.
How can I write this qith LINQ in a concise way ?
public static string CountMin(IList<string> inputList)
{
if (inputList == null || !inputList.Any()) return null;
var result = inputList.Select(s => new
{
Item = s,
Count => s.Count(ch => ch == 'X')
})
.OrderBy(item => item.Count).First().Item;
}
Snippet assumes that all elements on list are different to null. If you need it, it could be easily improved.
You can also omit temporary class:
inputList.OrderBy(s => s.Count(c => c == 'X')).First();
string[] list = {"AXBXX", "AAX", "AXX"};
string result = (from word in list
select new { word, wordLen = (word.Length - (word.Replace("X", "")).Length) })
.OrderBy(x => x.wordLen).First().word;
MessageBox.Show(result);
Here's an answer that will get you all of the minimum X strings from the list.
var listOfStrings = new List<string>()
{
"AXB",
"ABXXC",
"ABX",
};
var minimumXs =
listOfStrings
.GroupBy(x => x.Count(y => y == 'X'))
.OrderBy(x => x.Key)
.Take(1)
.SelectMany(x => x);
That gives me:
AXB
ABX
I'm trying to translate this sql statement
SELECT row, SUM(value) as VarSum, AVG(value) as VarAve, COUNT(value) as TotalCount
FROM MDNumeric
WHERE collectionid = 6 and varname in ('C3INEV1', 'C3INEVA2', 'C3INEVA3', 'C3INVA11', 'C3INVA17', 'C3INVA19')
GROUP BY row
into an EF 4 query using lambda expressions and am missing something.
I have:
sumvars = sv.staticvararraylist.Split(',');
var aavresult = _myIFR.MDNumerics
.Where(r => r.collectionid == _collid)
.Where(r => sumvars.Contains(r.varname))
.GroupBy(r1 =>r1.row)
.Select(rg =>
new
{
Row = rg.Key,
VarSum = rg.Sum(p => p.value),
VarAve = rg.Average(p => p.value),
TotalCount = rg.Count()
});
where the staticvararraylist has the string 'C3INEV1', 'C3INEVA2', 'C3INEVA3', 'C3INVA11', 'C3INVA17', 'C3INVA19' (without single quotes) and the _collid variable = 6.
While I'm getting the correct grouping, my sum, average, & count values aren't correct.
You didn't post your error message, but I suspect it's related to Contains. I've found that Any works just as well.
This should get you quite close:
var result =
from i in _myIFR.MDNumerics
where i.collectionid == _collid && sumvars.Any(v => i.varname == v)
group i by i.row into g
select new {
row = g.Key,
VarSum = g.Sum(p => p.value),
VarAve = g.Average(p => p.value),
TotalCount = g.Count()
};
Try this:
var aavresult = _myIFR.MDNumerics
.Where(r => r.collectionid == _collid && sumvars.Contains(r.varname))
.GroupBy(r1 =>r1.row,
(key,res) => new
{
Row = key,
VarSum = res.Sum(r1 => r1.value),
VarAve = res.Average(r1 => r1.value),
TotalCount = res.Count()
});