LINQ - How to select and count the right results - linq

I have 3 tables: DiaryPosts, DiaryImpressions, Impressions.
Impressions is a small list with some fields: 'like', 'dislike', 'agree', 'disagree'. The user can vote according to what he thinks about the post.
DiaryImpressions is the table that handles the relationship between the posts and the users who vote.
My problem is, I have to count results of each impression vote for each post, so maybe for one post 13 users voted for like, 2 for dislike, 34 agree and 1 disagree.
I have no idea how to perform the query in some way I can get this specific count results for each impression.
Can anyone help me with that?

You can do this via the GroupBy method. It allows you to automatically "group" the elements based on the impression, and count the results per group.

var post(from c in posts selec c)
string post1like;
string post2dislike;
string postagree3;
string postdisagree3;
foreach (var item in posts)
{
var ipressionslike=(from c in imressions where impressioid=item.id where c.impressionID='LIKE' select c.userID).Tolist()
var ipressionsdislike=(from c in imressions where impressioid=item.id where c.impressionID='disLIKE' select c.userID).Tolist()
var ipressionslike=(from c in imressions where impressioid=item.id where c.impressionID='LIKE' select c.userID).Tolist()
var ipressionsagree=(from c in imressions where impressioid=item.id where c.impressionID='disLIKE' select c.userID).Tolist()
post1like+=item.id+""+ipressionsdislike.count;
post2dislike+=item.id+""+ipressionslike.count;
postagree3+=item.id+""+ipressionsagree.count;
}
it should count the impressions for each post and count the amount of users that like or dislike so if you have 30 people dislike for each post it should get them I cannot see your table structure but I hope it will help or point you somewhere

I have to guess but here is what I think the SQL would look like:
SELECT I.Name, COUNT(I.Name)
FROM DairyPosts P
JOIN DairyImpressions DI ON P.ID=DI.DairyID
JOIN Impressions I ON DI.ImpressionsID = I.ID
And what the linq would look like:
List<Dairy> dairyposts = GetDairyPosts();
var impressionCounts =
from p in dairyposts
group p by p.ImpressionName into g
select new { Type = g.Key, ImpressionCount = g.Count() };
Of course I have to assume your list is created a certain way, if you can post how your list is actually created that would help. (As I said in the comments)

Related

Combining LINQ Queries to reduce database calls

I have 2 queries that work, I was hoping to combine them to reduce the database calls.
var locations = from l in db.Locations
where l.LocationID.Equals(TagID)
select l;
I do the above because I need l.Name, but is there a way to take the above results and put them into the query below?
articles = from a in db.Articles
where
(
from l in a.Locations
where l.LocationID.Equals(TagID)
select l
).Any()
select a;
Will I actually be reducing any database calls here?
This seems a bit complicated because Locations appears to be a multi-value property of Articles and you want to only load the correct one. According to this answer to a similar question you need to use a select to return them separately in one go so e.g.
var articles = from a in db.Articles
select new {
Article = a,
Location = a.Locations.Where(l => l.LocationId == TagId)
};
First failed attempt using join:
var articlesAndLocations = from a in db.Articles
join l in a.Locations
on l.LocationID equals TagID
select new { Article = a, Location = l };
(I usually use the other LINQ syntax though so apologies if I've done something stupid there.)
Could you not use the Include() method here to pull in the locations which are associated with each article, then select both the article and location object? or the properties you need from each.
The include method will ensure that you don't need to dip into the db twice, but will allow you to access properties on related entities.
You would need to use a contains method on an IEnumerable I believe, something like this:
var tagIdList = new List() { TagID };
var articles = from a in db.Articles.Include("Locations")
where tagIdList.Contains(from l in a.Locations select l.LocationID)
select new { a, a.Locations.Name };
(Untested)

Nested Query or Sub query linq

I have two classes. Bills and Transactions. One bill is made up of many transactions. I am able to display bills and I am able to display transactions on their own. But I would like to display the last 10 bills (this part is done), but each bill should show all its transactions.
This part of the code is used to get all transactions of a bill
{ Bill bill = (Bill)Bills.Instance.GetBillsByCustomerID(id);
//get all transactions of bill
var transactions = from t in this._entities.Transactions
where t.Bill.bID == bill.bID
select new
{
t.Product.pName, t.tQty, t.tUnitPrice, t.Bill.bTotal, t.Bill.bTimestamp, t.Bill.bCustomerIDF
};
}
Now I would like that the following query below, would have some sort of nested query where all transactions OF EACH BILL are obtained: (at the moment, this only displays 10 bills - and no transactions
{
//returns top 10
var bills = (from b in this._entities.Bills
where b.bCustomerIDF == id
orderby b.bTimestamp descending
select new { b.bTotal, b.bTimestamp, b.Customer.cName}).Take(10);
return bills;
}
Can you please guide me to a simple solution? Thank you
I believe you want a join with an into
var bills = (from b in this._entities.Bills
join t in this._entities.Transactions on t.Bill.bID equals b.bID into tg
where b.bCustomerIDF == id
orderby b.bTimestamp descending
select new
{
b.bTotal,
b.bTimestamp,
b.Customer.cName,
Transactions = tg
}
).Take(10);
return bills;
I would have thought that you should just be able to add something like the following into your select:
transactions.Where(x=>x.Bill.bID == b.bID)`
That having been said I do also think it sounds like your object model is wrong. I'd have expected a Bill to have a collection of Transactions that are on that Bill.

CRM 2011 - N:N (Many-To-Many) Linq Issue

I have two entities who are N:N - related with each other. With an example I'll show you what I mean :
I have a Session (ave_Session) and there we can put "Trainers"
(ave_trainer) on each Session
I'm tryting to get a list of al the
"Trainers" for a particular Session
They are related to each other in
N:N (relationship name : ave_ave_session_ave_trainer)
I work in VS2010 and with C# => I'm trying to get the data through LINQ
I recently just started with LINQ, so maybe you guys can help me out on this one. The following I've tried and i gave me an "AttributeFrom and AttributeTo must be either both specified or both ommited. You can not pass only one or the other. AttributeFrom: , AttributeTo: ave_trainerid"-error :
var formatteurs = (from f in ORGContext.CreateQuery<ave_trainer>()
join s in ORGContext.CreateQuery<ave_ave_session_ave_trainer>() on f.Id equals s.ave_trainerid.Value
join c in ORGContext.CreateQuery<ave_session>() on s.ave_sessionid.Value equals c.Id
where c.Id == item.Id
select f).ToList();
The item.id is the Id of the session. Thx in advance if you can help me out!
From the MSDN page:
// List the contacts in the Softball team marketing list.
System.Console.WriteLine("List all contacts in Softball Team:");
var members = from c in crm.contacts
join mlm in crm.listmembers on c.contactid equals mlm.entityid
join ml in crm.lists on mlm.listid equals ml.listid
where ml.listname == "Softball Team"
select c;
foreach (var c in members)
{
System.Console.WriteLine(c.fullname + " " + c.emailaddress1);
}
It seems a little backwards the way you have it written now (assuming I'm parsing it correctly).
What you'd normally do is put your 'starting thing' first and then go through the mapping to get to the ones you want. I don't have any CRM 2011 experience, so hopefully I didn't mess this up too much. :)
Also, I'm not a fan of single-character names, so I took the liberty of using longer names :)
var formatteurs = (
// first get the session we're interested in
from session in ORGContext.CreateQuery<ave_session>()
where session.Id == item.Id
// now get the mapping rows that are related to it
join mapping in ORGContext.CreateQuery<ave_ave_session_ave_trainer>()
on session.Id equals s.ave_sessionid.Value
// now get from the mapping rows to the actual trainers
join trainer in ORGContext.CreateQuery<ave_trainer>()
on mapping.ave_trainerid.Value equals trainer.Id
select trainer
).ToList();

LINQ to sharepoint . join list help

I am currently using SharePoint 2010,and in my business layer I am using LINQ to SharePoint. I generated all my Entity classes using SPMetal.
We are creating a Library system, my system has 2 Lists . The first one is Contribution and the second one is Contributor. Each Contributor contains a reference to the Contribution List (a PrimaryISBN reference). The Contribution List contains list of books and PrimaryISBN is not unique in this list.
Contribution
ID PrimaryISBN TITLE
1 PRIM1 HardcoverLOTR
2 PRIM1 AudioBookLOTR
3 PRIM2 HardcoverHP
Contributor
ID Name PrimaryISBNLookup
1 ABC PRIM1
2 DEF PRIM2
I am currently trying to fetch All the Books Contributed by a Particular user based on the Name.
My query is something like this
var result = from _contributor in data.contributor
where _contributor.Name= "ABC"
select new Book
{
Title = contributor.PrimaryISBNLookup.Title
}
The problem that I am currently facing is in retrieving records that have same ISBN but different title (Each format will have a title i.e. a Audio book will have a title and a Hardcover of the same book will have a different one).
This query returns me only 1 records even thought I have 2 records in my system i.e. the record with ID (in Contribution) that I am forced to insert during the insertion of record into Contributor List.
Your help is highly appreciated.
From what I understand, you try to implement a simple join, like this:
var results = from _contributor in data.contributor
join _contribution in data.contribution
on _contributor.PrimaryISBNLookup equals _contribution.PrimaryISBN
where _contributor.Name == "ABC"
select new Book
{
Title = _contribution.Title
}
If you want to use DataTable in SPList, try this:
SPList cList = spWeb.Lists.TryGetList("Customer");
SPList oList = spWeb.Lists.TryGetList("Order");
DataTable cTable= cList.Items.GetDataTable();
DataTable oTable= oList.Items.GetDataTable();
var coList = from tbl1 in cTable.AsEnumerable()
join tbl2 in oTable.AsEnumerable() on tbl1["Title"] equals tbl2["CustomerName"]
select new
{
ItemName = tbl2["Title"],
CustomerName = tbl1["Title"],
Mobile = tbl1["MobileNo"]
};

LINQ subquery question

Can anybody tell me how I would get the records in the first statement that are not in the second statement (see below)?
from or in TblOrganisations
where or.OrgType == 2
select or.PkOrgID
Second query:
from o in TblOrganisations
join m in LuMetricSites
on o.PkOrgID equals m.FkSiteID
orderby m.SiteOrder
select o.PkOrgID
If you only need the IDs then Except should do the trick:
var inFirstButNotInSecond = first.Except(second);
Note that Except treats the two sequences as sets. This means that any duplicate elements in first won't be included in the results. I suspect that this won't be a problem since the name PkOrgID suggests a unique ID of some kind.
(See the documentation for Enumerable.Except and Queryable.Except for more info.)
Do you need the whole records, or just the IDs? The IDs are easy...
var ids = firstQuery.Except(secondQuery);
EDIT: Okay, if you can't do that, you'll need something like:
var secondQuery = ...; // As you've already got it
var query = from or in TblOrganisations
where or.OrgType == 2
where !secondQuery.Contains(or.PkOrgID)
select ...;
Check the SQL it produces, but I think it should do the right thing. Note that there's no point in performing any ordering in the second query - or even the join against TblOrganisations. In other words, you could use:
var query = from or in TblOrganisations
where or.OrgType == 2
where !LuMetricSites.Select(m => m.FkSiteID).Contains(or.PkOrgID)
select ...;
Use Except:
var filtered = first.Except(second);

Resources