I have the following Linq queries which are getting the error below. My question is how can I use the T_EquipmentCompetency.Competency in a where clause but not have it in the group by or select list. I am fairly new to LINQ queries. Is there something that I am missing here?
using (EntitiesModel dbContext = new EntitiesModel())
{
var competencyForMachine = (from eq in dbContext.T_Equipmentcompetencies
where eq.MachineId == machineId
select eq.CompetencyId);
var competencyForEmployees = (from sm in dbContext.T_OHS_Skillsmatrices
join em in dbContext.T_Employees on sm.EmployeeID equals em.EmployeeID
where competencyForMachine.Contains(sm.CompentencyID)
group sm by new {sm.EmployeeID,em.FirstNameSTR,em.LastNameSTR} into g
where g.Count() == competencyForMachine.Count()
select new {g.Key.EmployeeID, g.Key.FirstNameSTR,g.Key.LastNameSTR});
foreach(var employee in competencyForEmployees)
{
RadMenuItem employeeItem = new RadMenuItem { Text= employee.FirstNameSTR + " " + employee.LastNameSTR, Value = employee.EmployeeID.ToString()};
Item.Items.Add(employeeItem);
}
}
This is the error I am getting
Telerik.OpenAccess.RT.sql.SQLException: Column
'dbo.T_EquipmentCompetency.CompetencyId' is invalid in the select list
because it is not contained in either an aggregate function or the GROUP BY clause.
The sql I am trying to emulate works in SQL Server
declare #MachineId int = 1
select sm.EmployeeID,em.FirstNameSTR,em.LastNameSTR
from T_OHS_SkillsMatrix sm
inner join T_Employees em on sm.EmployeeID = em.employeeId
where sm.CompentencyID in ( select CompetencyID
from T_EquipmentCompetency
where MachineId = #machineId
)
group by sm.EmployeeID,em.FirstNameSTR,em.LastNameSTR
having count(*) = (select count(*) from T_EquipmentCompetency where MachineId = #MachineId)
you got it mispelled
select eq.CompetencyId --- different spelling
sm.CompentencyID
while in sql sql server
where sm.CompentencyID in ( select CompentencyID
Related
How can I write a linq to entities query that includes a having clause?
For example:
SELECT State.Name, Count(*) FROM State
INNER JOIN StateOwner ON State.StateID = StateOwner.StateID
GROUP BY State.StateID
HAVING Count(*) > 1
Any reason not to just use a where clause on the result?
var query = from state in states
join stateowner in stateowners
on state.stateid equals stateowner.stateid
group state.Name by state.stateid into grouped
where grouped.Count() > 1
select new { Name = grouped.Key, grouped.Count() };
I believe you can use a GroupBy followed by a Where clause and it will translate it as a Having. Not entirely sure though.
If you want to compare a variable that is not in the group by (Ex: age), then it would be:
var duplicated = (
from q1 in db.table1
where (q1.age >= 10 )
group q1 by new { q1.firstName, q1.lastName } into grp
where (grp.Count() > 1 )
select new
{
firstName= grp.Key.firstName,
lastName = grp.Key.lastName,
}
);
I have this rather complex query in SQL server 2008:
declare #LanguageID as int = 1
select k.datePublish, k.dateEditing, k.dateTables
from TableAreasLevel1 as areaL1
inner join TableAreasLevel2 as areaL2
on areaL1.LanguageID = areaL2.LanguageID and
areaL1.CodeAreaLevel1 = areaL2.CodeAreaLevel1
inner join TableAreasLink as link
on areaL2.CodeAreaLevel1 = link.CodeAreaLevel1 and
areaL2.CodeAreaLevel2 = link.CodeAreaLevel2 and
inner join TableProducts as tblProds
on tblProds.CodeAreaLevel1 = areaL1.CodeAreaLevel1 and
tblProds.CodeAreaLevel2 = areaL2.CodeAreaLevel2
inner join TableSI_Products as prod
on prod.SiAreaCode = link.SiAreaCode
inner join TableCalendar as k
on k.KodTableSI_Products = tblProds.KodTableSI_Products
where areaL1.LanguageID = #LanguageID and
prod.Code = 'some string' and
k.LanguageID = #LanguageID and
tblProds.LanguageID = #LanguageID;
I am trying to develop the same query in LINQ, but I get error when I try join the table TableProducts, i.e the third consecutive join.
Here is my LINQ query:
List<Tuple<DateTime, DateTime, DateTime>> dates = (from areaL1 in gpe.TableAreasLevel1
join areaL2 in gpe.TableAreasLevel2
on new { areaL1.CodeAreaLevel1, areaL1.LanguageID } equals
new { areaL2.CodeAreaLevel1, areaL2.LanguageID }
join link in gpe.TableAreasLink
on new { areaL2.CodeAreaLevel1, areaL2.CodeAreaLevel2, areaL2.RbrOblastNivo2} equals
new {link.CodeAreaLevel1, link.CodeAreaLevel2}
join tblProds in gpe.TableProducts
on tblProds. // The name tblProds is not in the scope of the left side of 'equals'
);
Is the problem connected with how the tables are designed or, something else I should check for?
Any ideas, why tblProds is not visible in the scope of the LINQ query?
You are using Query as your guide something like:
on k.KodTableSI_Products = tblProds.KodTableSI_Products
but take a look at your linq:
on new { areaL1.CodeAreaLevel1, areaL1.LanguageID } equals
it has two fields. I think its not a good idea.
linq join something like
var dates = (from areaL1 in gpe.TableAreasLevel1
join areaL2 in gpe.TableAreasLevel2
on areaL1.PKFields equals areaL2.PKFields
where areaL1.CodeAreaLevel1== areaL2.CodeAreaLevel1 && areaL1.LanguageID = areaL2.LanguageID
Select new YournewClass{YournewClass.Field1=areaL1.fields1, And so on}
)
You can do to join the other tables with aliases.
Sorry need to go for now.
I'm giving you an idea.
Hope it helps.
I am trying to move from simple SQL to EF.
But there are some complex queries(joins) that it seems to hard to generate the linq for.
At first I tried to use sqltolinq tool to generate the linq but it gives error as some of the things are not supported in the query.
here is the linq:
var entryPoint = (from ep in dbContext.tbl_EntryPoint
join e in dbContext.tbl_Entry on ep.EID equals e.EID
join t in dbContext.tbl_Title on e.TID equals t.TID
where e.OwnerID == user.UID
select new {
UID = e.OwnerID,
TID = e.TID,
Title = t.Title,
EID = e.EID
});
The table entry has many entries that I would like to group and get the latest for each group. But then I would need to select into a view model object which will be bind to gridview.
I dont know where I can implement the logic to group by and get the latest from each and be able to get values from join table into viewModel object.
somewhere I need to add
group entry by new
{
entry.aID,
entry.bCode,
entry.Date,
entry.FCode
}
into groups
select groups.OrderByDescending(p => p.ID).First()
in the above linq to retrieve latest from each group.
You can insert group by right after the joins:
var query =
from ep in dbContext.tbl_EntryPoint
join e in dbContext.tbl_Entry on ep.EID equals e.EID
join t in dbContext.tbl_Title on e.TID equals t.TID
where e.OwnerID == user.UID
group new { ep, e, t } by new { e.aID, e.bCode, e.Date, e.FCode } into g
let r = g.OrderByDescending(x => x.e.ID).FirstOrDefault()
select new
{
UID = r.e.OwnerID,
TID = r.e.TID,
Title = r.t.Title,
EID = r.e.EID
};
The trick here is to include what you need after the grouping between group and by.
However, the above will be translated to CROSS APPLY with all joins included twice. If the grouping key contains fields from just one table, it could be better to perform the grouping/selecting the last grouping element first, and then join the result with the rest:
var query =
from e in (from e in dbContext.tbl_Entry
where e.OwnerID == user.UID
group e by new { e.aID, e.bCode, e.Date, e.FCode } into g
select g.OrderByDescending(e => e.ID).FirstOrDefault())
join ep in dbContext.tbl_EntryPoint on e.EID equals ep.EID
join t in dbContext.tbl_Title on e.TID equals t.TID
select new
{
UID = e.OwnerID,
TID = e.TID,
Title = t.Title,
EID = e.EID
};
I have the following MSSQL query I am trying to convert to LINQ. I am using entity framework with the following syntax to get at the data.
var rv = (from i in DC.TableA select i).ToList();
This is the sql I want to write a C# LINQ query for but I cannot figure it out. Can someone help?
select BTO.*
from TableA BTO
join
(
select eqnum, max(testdate) as testdate
from TableA BTO1
where
BTO1.eqnum in ('M0435', 'Z0843') and
BTO1.testdate <= '2008-06-01'
group by eqnum
) T1
on
T1.eqnum = BTO.eqnum and
T1.testdate = BTO.testdate
order by EqNum;
I think there is opportunity to rewrite your query, but for information purposes I rewrote your sql into linq verbatim.
If you explain what you are trying to achieve we can provide alternative sql / linq
var eqnums = new[] { "M0435", "Z0843" };
var testdate = "2008-06-01";
var query = from bto in DC.TableA
join t1 in (
from bto1 in DC.TableA
where eqnums.Contains(bto1.eqnum) &&
bto1.testdate.CompareTo(testdate) <= 0
group bto1 by bto1.eqnum into g
select new
{
eqnum = g.Key,
testdate = g.Max(x => x.testdate)
}
) on new { bto.eqnum, bto.testdate } equals new { t1.eqnum, t1.testdate }
orderby bto.eqnum
select bto;
I have a problem creating the following SQL Statement using LINQ & C#
select c.IDAddenda, c.Descripcion
from CatAddendas c
right join EmpresaAddenda e on e.IDAddenda = c.IDAddenda
where e.rfc = 'SUL010720JN8'
order by c.IDAddenda asc
I got this:
public IEnumerable<CatAddenda> TraeAddendas(string rfc)
{
DataClasses1DataContext dc = new DataClasses1DataContext(...);
return (from adds in dc.EmpresaAddendas
cats.IDAddenda into joined
where adds.RFC == rfc
select adds.CatAddenda);
}
This is not doing a right join, so any ideas?
var RightJoin = from adds in dc.EmpresaAddendas
join cats in CatAddendas
on adds.IDAddenda equals cats.IDAddenda into joined
from cats in joined.DefaultIfEmpty()
select new
{
Id = cats.IDAddenda,
Description = cats.Descripcion
};
var results = from e in EmpresaAddenda
join c in CatAddendas
on e.IDAddenda equals c.IDAddenda into f
from c in f.DefaultIfEmpty()
select new
{
ID = c.IDAddenda,
Description = c.Descripcion
};
You can apply where and order by on the results.