Reputation: 23
I don't know what's wrong with this query - it keeps giving me this error:
Unable to create a constant value of type 'OvertimeProject.DataCore.tbl_Promotion'. Only primitive types or enumeration types are supported in this context.
Here is my linq statement:
public IEnumerable<StaffJoin> GetOrderStaffByDepartment(int DepID, DateTime DATE)
{
using (var Context = new CRMDBEntities())
{
var result = (from pro2 in Context.tbl_Promotion
where pro2.PromotionDate <= DATE && pro2.DepID==DepID
select pro2).ToList();
var result2 = (from Re in result
group Re by Re.StaffID into g2
join prop in Context.tbl_Promotion on g2.Max(c => c.PromotionID) equals prop.PromotionID
select prop).ToList();
var result3 = (from s in Context.tbl_STaff
join
promotion in result2 on s.StaffID equals promotion.StaffID
join
position in Context.tbl_Position on promotion.PositionID equals position.PositionID
select new StaffJoin{Staff= s,Promotion= promotion,Position= position}).ToList();
return result3;
}
}
Here is my class which I want to fill with returned data:
public class StaffJoin
{
public tbl_STaff Staff { get; set; }
public tbl_Promotion Promotion { get; set; }
public tbl_Position Position { get; set; }
}
... And here is my model instructure with navigated properties:
tbl_Staff tbl_Promotion tbl_Position
--------- -------------- -------------
StaffID 0.1 PromotionID 0.1 PositionID
DepID PromotionDate PositionName
StaffName * StaffID PositionBase
Chek PositionID * Avaiilibilty
Avilibility
------- --------------- --------------
Navigation Navigation Navigation
---------- -------------- ----------------
tbl_Department tbl_Position tbl_Promotion
tbl_Promotion tbl_Staff
What I need is this:
All staff for a specific department plus the max promotion for each staff member after a specific date, plus the position info related to the promotion
Upvotes: 1
Views: 1128
Reputation: 15772
Your problem is that your code basically reads like this...
public IEnumerable<StaffJoin> GetOrderStaffByDepartment(int DepID, DateTime DATE)
{
using (var Context = new CRMDBEntities())
{
List<Promotion> result = (from pro2 in Context.tbl_Promotion
where pro2.PromotionDate <= DATE && pro2.DepID==DepID
select pro2).ToList();
List<Promotion> result2 = (from Re in result
group Re by Re.StaffID into g2
join prop in Context.tbl_Promotion on g2.Max(c => c.PromotionID) equals prop.PromotionID
select prop).ToList();
var result3 = (from s in Context.tbl_STaff
join
promotion in result2 on s.StaffID equals promotion.StaffID
join
position in Context.tbl_Position on promotion.PositionID equals position.PositionID
select new StaffJoin{Staff= s,Promotion= promotion,Position= position}).ToList();
return result3;
}
}
Now on result3, you are trying to put two List<Propmotion>
into a Linq query, which LinqToSQL needs to convert into SQL. Obviously SQL can't handle .net user classes, so it fails.
If you consider Jeff's change you will get
public IEnumerable<StaffJoin> GetOrderStaffByDepartment(int DepID, DateTime DATE)
{
using (var Context = new CRMDBEntities())
{
IQueryable<Promotion> result = (from pro2 in Context.tbl_Promotion
where pro2.PromotionDate <= DATE && pro2.DepID==DepID
select pro2);
IQueryable<Promotion> result2 = (from Re in result
group Re by Re.StaffID into g2
join prop in Context.tbl_Promotion on g2.Max(c => c.PromotionID) equals prop.PromotionID
select prop);
var result3 = (from s in Context.tbl_STaff
join
promotion in result2 on s.StaffID equals promotion.StaffID
join
position in Context.tbl_Position on promotion.PositionID equals position.PositionID
select new StaffJoin{Staff= s,Promotion= promotion,Position= position}).ToList();
return result3;
}
}
Now, LinqToSQL knows how to deal with IQueryables. It could just inline the SQL in result and result2 as subqueries. Hence the difference.
However the last thing you need to change is the last line. IQueryable<T>
represents a query, work that hasn't happened yet. It is when you call .GetEnumerator()
that the query actually runs. However, that will only occur in the consuming code, by which point the CRMDBEntities
will have been disposed. Soooo.....
public IEnumerable<StaffJoin> GetOrderStaffByDepartment(int DepID, DateTime DATE)
{
using (var Context = new CRMDBEntities())
{
IQueryable<Promotion> result = (from pro2 in Context.tbl_Promotion
where pro2.PromotionDate <= DATE && pro2.DepID==DepID
select pro2);
IQueryable<Promotion> result2 = (from Re in result
group Re by Re.StaffID into g2
join prop in Context.tbl_Promotion on g2.Max(c => c.PromotionID) equals prop.PromotionID
select prop);
var result3 = (from s in Context.tbl_STaff
join
promotion in result2 on s.StaffID equals promotion.StaffID
join
position in Context.tbl_Position on promotion.PositionID equals position.PositionID
select new StaffJoin{Staff= s,Promotion= promotion,Position= position}).ToList();
return result3.ToList();
}
}
Or with the var
s back...
public IEnumerable<StaffJoin> GetOrderStaffByDepartment(int DepID, DateTime DATE)
{
using (var Context = new CRMDBEntities())
{
var result = (from pro2 in Context.tbl_Promotion
where pro2.PromotionDate <= DATE && pro2.DepID==DepID
select pro2);
var result2 = (from Re in result
group Re by Re.StaffID into g2
join prop in Context.tbl_Promotion on g2.Max(c => c.PromotionID) equals prop.PromotionID
select prop);
var result3 = (from s in Context.tbl_STaff
join
promotion in result2 on s.StaffID equals promotion.StaffID
join
position in Context.tbl_Position on promotion.PositionID equals position.PositionID
select new StaffJoin{Staff= s,Promotion= promotion,Position= position}).ToList();
return result3.ToList();
}
}
Upvotes: 2