linq-to-sql出错:无法创建类型的常量值

时间:2013-05-09 00:13:47

标签: c# linq entity-framework linq-to-sql

我不知道这个查询有什么问题 - 它一直给我这个错误:

  

Unable to create a constant value of type 'OvertimeProject.DataCore.tbl_Promotion'. Only primitive types or enumeration types are supported in this context.

这是我的linq声明:

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;
    }
}

这是我想要填充返回数据的类:

 public class StaffJoin
 {
     public tbl_STaff Staff { get; set; }
     public tbl_Promotion Promotion { get; set; }
     public tbl_Position Position { get; set; }  
 }

......这是我的模型结构,带有导航属性:

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

我需要的是:

特定部门的所有员工加上每个员工在特定日期之后的最大促销,以及与促销相关的职位信息

1 个答案:

答案 0 :(得分:2)

您的问题是您的代码基本上是这样的......

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;
    }
}

现在在result3上,您尝试将两个List<Propmotion>放入Linq查询中,LinqToSQL需要将其转换为SQL。显然SQL无法处理.net用户类,因此失败。

如果你考虑杰夫的改变,你会得到

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;
    }
}

现在,LinqToSQL知道如何处理IQueryables。它可以将结果中的SQL和result2作为子查询内联。因此存在差异。

然而,你需要改变的最后一件事是最后一行。 IQueryable<T>表示查询,尚未发生的工作。当您调用.GetEnumerator()时查询实际运行。但是,这只会在消费代码中出现,此时CRMDBEntities将被处理掉。 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();
    }
}

或者var返回...

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();
    }
}