LINQ in LinqPad count how many times a word shows up - linq

I am trying to write a LINQ query that counts how many times <p> and </p> shows up.
from d in IPACS_Documents
join dp in IPACS_ProcedureDocs on d.DocumentID equals dp.DocumentID
join p in IPACS_Procedures on dp.ProcedureID equals p.ProcedureID
where d.DocumentID == 4
& d.DateDeleted == null
select ??
The select is where I am stuck. The column I need to count how many times <p> is in d.Html the same for </p>

I'm not sure there's a Linq-To-SQL/Entities way to complete this, since SQL doesn't do this easily.
var result = (from d in IPACS_Documents
join dp in IPACS_ProcedureDocs on d.DocumentID equals dp.DocumentID
join p in IPACS_Procedures on dp.ProcedureID equals p.ProcedureID
where d.DocumentID == 4
&& d.DateDeleted == null
select d.Html).First();
int count = Regex.Matches(result, "<p>|</p>").Count;
will probably do it.

Related

Linq query - ON clause of inner join cannot compare two Guids

If the person you are searching is a CIA emplyee, take his CIAJobs.EmployerID, otherwise select People.ID
SELECT
case when CIAJobs.EmployeeID IS NULL then People.ID
else CIAJobs.EmployerID
end
FROM [FMO].[People] AS p
LEFT JOIN [FMO].[CIAJobs] j
ON (p.ID = j.[EmployeeID])
AND (j.[relationshipType] = '25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
where p.ID = '1b66e032-94b2-e811-96e0-f48c508e38a2' // id of person you search for
OR
j.[EmployeeID] = '1b66e032-94b2-e811-96e0-f48c508e38a2' // id of person you search for
I tried doing this in Linq:
var a = from l in People
join x in CIAJobs
on l.Id equals x.EmployeeID && x.RelationshipTypeGuid equals Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx.EmployeeID == null) ? l.EmployeeId : x.EmployerID;
var b = a.ToList();
why does the query show an error because of this chunk: && x.RelationshipTypeGuid equals Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
If I remove this part it shows no error.
Error is: operator && cannot be applied to operands of type Guid and Guid.
Can you help me correct the Linq query please logically and syntactically? Thank you.
You don't need join for multiple conditions in this scenario. Use this
var a = from l in People
join x in CIAJobs
.Where(z=>z.RelationshipTypeGuid
.Equals(Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')))
on l.Id equals x.EmployeeID
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx.EmployeeID == null) ? l.EmployeeId : x.EmployerID;
var b = a.ToList();
But based on your problem statement this should do
var a = from l in People
join x in CIAJobs
on l.Id equals x.EmployeeID
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx == null) ? l.EmployeeId : xx.EmployerID;
var b = a.ToList();

SQL to LINQ with JOIN and SubQuery

I have a query that I' struggling to convert to LINQ. I just can't get my head around the required nesting. Here's the query in SQL (just freehand typed):
SELECT V.* FROM V
INNER JOIN VE ON V.ID = VE.V_ID
WHERE VE.USER_ID != #USER_ID
AND V.MAX > (SELECT COUNT(ID) FROM VE
WHERE VE.V_ID = V.ID AND VE.STATUS = 'SELECTED')
The Closest I've come to is this:
var query = from vac in _database.Vacancies
join e in _database.VacancyEngagements
on vac.Id equals e.VacancyId into va
from v in va.DefaultIfEmpty()
where vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == v.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
...which correctly resolves the subquery from my SQL statement. But I want to further restrict the returned V rows to only those where the current user does not have a related VE row.
I've realised that the SQL in the question was misleading and whilst it led to technically correct answers, they weren't what I was after. That's my fault for not reviewing the SQL properly so I apologise to #Andy B and #Ivan Stoev for the misleading post. Here's the LINQ that solved the problem for me. As stated in the post I needed to show vacancy rows where no linked vacancyEngagement rows existed. The ! operator provides ability to specify this with a subquery.
var query = from vac in _database.Vacancies
where !_database.VacancyEngagements.Any(ve => (ve.VacancyId == vac.Id && ve.UserId == user.Id))
&& vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == vac.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
This should work:
var filterOutUser = <userId you want to filter out>;
var query = from vac in _database.Vacancies
join e in _database.VacancyEngagements
on vac.Id equals e.VacancyId
where (e.UserId != filterOutUser) && vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == vac.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
select vac;
I removed the join to VacancyEngagements but if you need columns from that table you can add it back in.

linq join with less than or equal to int value

I wanting to know the best approach for a where clause with less than or equal to where the value to match is int?
var outOfStockProducts = (from theMapProd in context.tblProductOptions_MAP
join theProd in context.tblProducts on theMapProd.productID equals theProd.productID
where theProd.stock_Level <= 5
select theMapProd).ToList();
This is another way,
Not tested.
var outOfStockProducts = (from theMapProd in context.tblProductOptions_MAP
join theProd in context.tblProducts on theMapProd.productID equals theProd.productID
select theMapProd).ToList();
outOfStockProducts=outOfStockProducts.where(x=>x.stock_Level < 5 || x.stock_Level ==5).ToList();

many to many relationship

I am trying to write a linq to get data from many to many tables.
Here are the tables
Products (ID,Name,Description)
Products_Items (ID,ProductID,Description)
ProductsNeeds (ID,Name)
ProductsItems_Needs (ItemID,NeedsID)
This is the t-sql query
select gPro.Name,gProItems.ShortDescription,gProItems.Description,gNeeds.Name
from Products gPro
join Products_Items gProItems on gPro.ID = gProItems.ProductID
join ProductsItems_Needs gProNeeds on gProNeeds.ItemID = gProItems.ID
join ProductsNeeds gNeeds on gNeeds.ID = gProNeeds.NeedsID
where gProItems.ID = 1
this is the linq
var q = from p in objM.Products
join gpItems in objM.Products_Items on p.ID equals gpItems.ProductID
from needs in gpItems.ProductsNeeds
where gpItems.ID == 1
select p;
This query returns (Products) and it has the Produts_Items but it has not the ProductsNeeds.
What modifications should I do in order each Products_items to have the ProductsNeeds?
Thanks
Finally I found the solution.
The change was that instead of returning Products it returns Product_Items.
var q = from pItems in objM.Products_Items
join p in objM.Products on pItems.ID equals p.ID into joinedProducts
from p in joinedProducts.DefaultIfEmpty()
from needs in pItems.ProductsNeeds
where pItems.ID == 1
select pItems;

How do I do a table join on two fields in my second table?

I have two tables:
Messages - Amongst other things, has a to_id and a from_id field.
People - Has a corresponding person_id
I am trying to figure out how to do the following in a single linq query:
Give me all messages that have been sent to and from person x (idself).
I had a couple of cracks at this.
Not quite right
MsgPeople = (from p in db.people
join m in db.messages on p.person_id equals m.from_id
where (m.from_id == idself || m.to_id == idself)
orderby p.name descending
select p).Distinct();
This almost works, except I think it misses one case:
"people who have never received a message, just sent one to me"
How this works in my head
So what I really need is something like:
join m in db.messages on (p.people_id equals m.from_id or p.people_id equals m.to_id)
Gets me a subset of the people I am after
It seems you can't do that. I have tried a few other options, like
doing two joins:
MsgPeople = (from p in db.people
join m in db.messages on p.person_id equals m.from_id
join m2 in db.messages on p.person_id equals m2.to_id
where (m2.from_id == idself || m.to_id == idself)
orderby p.name descending
select p).Distinct();
but this gives me a subset of the results I need, I guess something to
do with the order the joins are resolved.
My understanding of LINQ (and perhaps even database theory) is embarrassingly superficial and I look forward to having some light shed on my problem.
People which sent messages to self or recieved messages from self.
from p in People
where p.SentMessages.Any(m => m.to_id == idself)
|| p.ReceivedMessages.Any(m => m.from_id == idself)
select p;
If your People don't have a these Messages properties, create the associations.
If you want to pull teeth instead... here's the same query without associations.
IQueryable<int> sentQuery =
from sent in Messages
where sent.to_id = idself
select sent.from_id;
IQueryable<int> receivedQuery =
from received in Messages
where received.from_id = idself
select received.to_id
IQueryble<People> result =
from p in people
where System.Linq.Queryable.Concat(receivedQuery, sentQuery)
.Any(id => id == p.personId)
select p;
maybe I am missing something but it seems you dont need a join, you say "Give me all messages that have been sent to and from person x (idself)." so if you just want the messages you can work from just he message table, as the id (idself) is known
var MsgPeople from p in AllMessages
where p.from_id == idself || p.to_id == idself
select p;
ok, try this, you realy need a list of ids for people who sent you messages, and a list of ones that recieved messages from you, then you can select from People any people that exist in that list
var MsgPeople = from p in db.people
where (from m in db.messages
where m.from_id == selfid
select m.to_id).Union(
from m in db.messages
where m.to_id == selfid
select m.from_id).Contains(p.person_id)
select p;
another way to do this, one I got from reverse engineering SQL from our DBA when I posed the question to him
var MsgPeople = from p in Peoples
where p.Person_id != selfid &&
(from m in Messages
where m.To_id == selfid select m.From_id).Union(
from m in Messages
where m.From_id == selfid select m.To_id).Contains(p.Person_id)
select p;
maybe try a union
select all the messages sent by user received by me
union
select all the messages received by user sent by me

Resources