Getting only the highest value in the database - c#

public ActionResult List_of_Winners(int id=0)
{
var winners = (from cat in db.Events_Category_tbl
join can in db.Candidates_Info_tbl
on cat.events_category_id equals can.events_category_id
where cat.events_info_id == id
select new Candidates
{
events_category_name = cat.events_category_name,
candidates_fullname = can.candidates_fullname,
candidates_info_id = can.candidates_info_id,
events_category_id = cat.events_category_id,
no_of_votes = can.no_of_votes.Value
}).OrderBy(x => x.no_of_votes).Distinct();
return PartialView(winners);
}
I have 2 tables, the Events_Category_tbl & Candidates_Info_tbl then in one category there are many candidates registered. Then, what I want to do is that I need to get only the highest votes in the category. And this serve as the winner of the category.
My Candidates table looks like this:
candidates_info_id,
candidates_fullname,
events_category_id,
no_of_votes
My Category table looks this way:
events_category_id,
events_category_name
Then, I want a result in my query that in one category it has one winner of the candidates the one got the highest votes.
How am I gonna do that?
Above is my code.

Related

Referencing a row from another table c# linq

I want to use an id from one table to list a title from another table in wpf, so i did this:
var q = from a in context.associations
select a;
associations = q.ToList();
associationViewSource.Source = associations;
foreach (var item in q)
{
var qTitles = from b in context.textbooks
where b.Id == item.book_id
select b.Title;
assocListView.ItemsSource = qTitles.ToList();
}
in the first portion of the code i am making the main body of the information, it lists all the information from associations table, after that i want to list the relevant titles from textbooks table, thats where i add items to the assocListview, but it of course fails and the data isn't displayed, no errors are thrown either. i hope i was clear enough.
Please help
You can get a list of Titles that have associations with a join...
var qTitles = context.textbooks
.Join(context.associations,
b => b.Id,
a => a.book_id,
b => b.Title)
.ToList();
The intention of the code isn't clear though because assocListView.ItemsSource is assigned to in each iteration of the loop. Is that a bug?
Since you are setting assocListView.ItemsSource each pass through the loop, the resultant list will have the results of the last query.
If you want a list of all associated titles you can get it with a single query:
var titles =
from a in context.associations
join b in context.textbooks on a.book_id equals b.Id
select b.Title;
assocListView.ItemsSource = titles.ToList();
This will return every title linked to any record in your associations table, in no particular order, with duplicates, etc. Normally it makes sense to extract a little more information to make it more usable. For instance, define a structure to hold an associated title:
public struct AssocTitle
{
public int AssocID;
public int BookID;
public string Title;
}
Then query it like:
var titles =
from a in context.associations
join b in context.textbooks on a.book_id equals b.Id
select new AssocTitle { AssocID = a.Id, BookID = b.Id, Title = b.Title };
Then when you click on things in the list view you can find out which book and which association, even if you have lots of associations with the same titles.

Take with group order by

I have a web app for calculating the results of a competition:
The competitors attempt x number of activities (each activity is assigned a point value) over several hours.
Their total score is the sum of the 5 highest point values.
I have the following code in my controller. I have tried using .Take(5) in several places but it returns either the top 5 scores only, or the first 5 entered in the table.
The grouping is over several fields as the competitors are awarded prizes by Category (age) and by Gender. I am using a viewmodel named "Game". My most recent unsuccessful code block:
var compdata = from result in db.Results
where result.Complete == true
orderby result.Activity.Value descending
group result by new
{
result.CompetitorId,
result.Competitor.Name,
result.Competitor.Category,
result.Competitor.Gender,
}
into resultsGroup
select new Game
{
CompetitorId = resultsGroup.Key.CompetitorId,
Name = resultsGroup.Key.Name,
Category = resultsGroup.Key.Category,
Gender = resultsGroup.Key.Gender,
Score = resultsGroup.Sum(s => s.Activity.Value)
};
I think you're almost there. When working out the Score value, you need do the Take(5) at that point ... after the grouping. The following isn't the most succinct way to do it but it demonstrates the point based on what you have right now:
Score = resultsGroup.OrderByDescending(s => s.Activity.Value).Take(5).Sum(s => s.Activity.Value)
So that gives something similar to:
var compdata = from result in db.Results
where result.Complete == true
group result by new
{
result.CompetitorId,
result.Competitor.Name,
result.Competitor.Category,
result.Competitor.Gender,
}
into resultsGroup
select new Game
{
CompetitorId = resultsGroup.Key.CompetitorId,
Name = resultsGroup.Key.Name,
Category = resultsGroup.Key.Category,
Gender = resultsGroup.Key.Gender,
Score = resultsGroup.OrderByDescending(s => s.Activity.Value).Take(5).Sum(s => s.Activity.Value)
};

Inner Join on Entity Framework

There is a table name Product:
|ProductID|ProductName|
1 abc
2 xyz
and there is another table Product Status.
The column Result in the below has three values:
Result
Value | Meta
0 Not checked
1 Failed
2 Passed
ProductCheckList
ID(AutoGenerated) | ProductID(Foreign Key) | Stage | Result |
1 1 1 1
2 1 2 2
In this table every product has to go through five different stages. If the product passes all the stages then the product is given quality checked status , If the product fails any on of the stages is is given as quality failed and send back to production.
I have to show a list of all the products with there quality status and depending on its quality state highlight the row with different row color. We are using Entity Framework and I am new to this.
I have thought of making a wrapper class for this.
Public class ProductWrapper
{
public Product product{get;set;}
Public string QualityStatus{get;set;}
public string BgColor {get;set;}
}
I am writing this LINQ query:
UtilitiesEntities context = new UtilitiesEntities();
List<ProductWrapper> wrapperList = new List<ProductWrapper>();
var request = from product in context.Product
join productCheck in context.ProductCheckList
on product.productId equals productCheck .productID
// may be do group by or something i get the result and assign the values.
select new List<ProductWrapper>
{
};
I am not able to write the query and add the where condition to fetch the result a list of wrapper class to pass to my view with the desired result.
If I understood correctly your request, you want something like this:
string goodQualityColor = "Green";
string badQualityColor = "Red";
string notCheckedColor = "Gray";
string notCheckedStatus = "Not Checked";
string failedStatus = "Failed";
string passedStatus = "Passed";
Dictionary<int,string> results= new Dictionary<int,string>();
results.Add(2,goodQualityColor);
results.Add(1,badQualityColor);
results.Add(0,notCheckedColor);
Dictionary<int,string> qualityStatuses = new Dictionary<int,string>();
results.Add(2,passedStatus);
results.Add(1,failedStatus);
results.Add(0,notCheckedStatus);
var request = (from product in context.Product
join productCheck in context.ProductCheckList
on product.productId equals productCheck.productID
select new
{
Product = product,
QualityStatus = productCheck.Result,
Result = productCheck.Result
}).ToList();
var finalResults = (from req in request
select new ProductWrapper
{
Product = req.Product,
QualityStatus = qualityStatuses.FirstOrDefault(s => s.Key == req.QualityStatus).Value,
BgColor = results.FirstOrDefault (s => s.Key == req.Result).Value
}).ToList<ProductWrapper>();
I would create an outer join using the into keyword and then do my statusCheck in the select part.
Could would look something like this :
var data = (from product in context.Product
join productCheck in context.ProductCheckList on product.productId equals productCheck.productID into productChecks
select new ProductWrapper
{
product = product,
passedBool = productChecks.All(pc => pc.Result == 2) && productChecks.Count() == 5
}).ToList();

Get list of child records

I have a database that looks like this:
tbl_Seminar
ID
isActive
tbl_SeminarFees
ID
seminar_id -- foreign key
fee_text
I want to get all seminars that are active (isActive ==1) and a list of the fees associated with that seminar. Each Seminar may have n records in tbl_SeminarFees that are its fees. I am able to return a linq structure that returns me a list of objects that look like this {seminar, SeminarFee} but I wanted to create a nested structure that looks like this:
{seminar, List<SeminarFee>}
What should my linq query look like?
here is my linq currently:
var results = from s in context.Seminar
join p in context.SeminarFees on
s.ID equals p.SeminarID
where s.IsActive == 1
select new
{
Seminar = s,
Fees = p
};
How do I change this to get a list of these: {seminar, List<SeminarFee>}
Thanks
UPDATE
#lazyberezovsky gave me a good idea to use a group join and into another variable. But then how do I loop through the result set. Here is what I have now:
foreach (var seminarAndItsFeesObject in results)
{
//do something with the seminar object
//do something with the list of fees
}
This however gives me the following error:
Argument type 'SeminarFees' does not match the
corresponding member type
'System.Collections.Generic.IEnumerable`1[SeminarFees]'
What am I doing wrong?
Thanks
You can use group join which groups inner sequence items based on keys equality (a.k.a. join..into) to get all fees related to seminar:
var results = from s in context.Seminar
join f in context.SeminarFees on
s.ID equals f.SeminarID into fees // here
where s.IsActive == 1
select new
{
Seminar = s,
Fees = fees
};
You can't call ToList() on server side. But you can map results on client later.
BTW You can define navigation property Fees on Seminar object:
public virtual ICollection<SeminarFee> Fees { get; set; }
In this case you will be able load seminars with fees:
var results = context.Seminar.Include(s => s.Fees) // eager loading
.Where(s => s.IsActive == 1);
var results = from s in context.Seminar
join p in context.SeminarFees on s.ID equals p.SeminarID
where s.IsActive == 1
group p by s into grouped
select new {
Seminar = grouped.Key,
Fees = grouped.ToList()
};

Linq grouping with list

I have an entity like this
Product Room
long productid long roomid
List<Room> rooms string roomname
String name
Now I have a list of Product entities which has duplicate date apart from list of rooms.
Eq.
Product
Id 1 Id2 Id3
Rooms = 1,A Rooms = 1,B Rooms =1,C
ABC ABC ABC
In this case I have the same property repeated 3 times because it got 3 rooms.
What I am trying to do is add all the rooms to one Product entity which will have one product entity and list of rooms (list of 3 in this case).
I tried something like this but it doesn’t work.
here I am passing the property id
var result = from t in Product
where t.ProductId == propId
group t by t.Rooms
into g
select g;
Any help or idea please
How about this?
var product = Product.First(p => p.ProductId == propId);
product.Rooms = from p in Product
from r in p.Rooms
select r;
If you just need to get the list of rooms that are associated with any of the products, you could try this:
var query = from t in products
select t;
var rooms = query.Aggregate(new List<Room> { }.AsEnumerable(), (i, p) => i.Union(p.rooms));
Note that the aggregation will NOT be executed as an sql query (if you are pulling data out of a db) - rather, it will be performed in memory.
I'm not sure if this is the result you wanted, but it will get you a list of rooms that are in the "rooms" property of all of the products combined. For example, if you have one product with rooms "A" and "B", and another product with "C", the resulting list of rooms will contain "A", "B", and "C".

Categories