将多个SQL JOIN转换为实体框架

时间:2017-08-04 05:47:43

标签: c# asp.net entity-framework linq

我试图转换此SQL查询:

select t.id,t.name as table_name,r.name as room_name,iif(c.id is null ,0,1) as opened,
 from gs_pos_t t
inner join gs_pos_r r on t.id_r=r.id
left join gs_pos_c c on t.id=c.id_t
left join gs_pos_pz p on c.id=p.id_c
 where c.open_date is not null
 group by 1,2,3,4

我需要选择所有房间的所有桌子和状态,如果有开放的销售,在这种情况下是当前开放销售的总和

我试过没有这样的运气:

        db.GS_POS_t.Join(
                      db.GS_POS_r,
                      t => t.ID_r,
                      r => r.ID,
                   (tables, rooms) => new {tables,rooms})
               .GroupJoin(
                     db.GS_POS_C
                       .GroupJoin(
                           db.GS_POS_C_PZ,
                           c => c.ID,
                           p => p.ID_C,
                           (sales, p) => new { sales, s_detail= p.DefaultIfEmpty() }
                           )
                           ,
                     mg => mg.tables.ID,
                     cg => cg.sales.ID_t,
                     (tablesrooms, saleswithdetail) => new { tablesrooms, saleswithdetail }
                ).Where(r => r.saleswithdetail.) <=Here !!!!
            );

这是模型:

GS_POS_T  (tables)
        public long ID { get; set; }
        public short ID_R { get; set; }
        public string NAME { get; set; }
        public virtual ICollection<GS_POS_C> GS_POS_C { get; set; }
        public virtual GS_POS_R GS_POS_R { get; set; }
       ...

GS_POS_R (rooms)

        public short ID { get; set; }
        public string NAME { get; set; }
        public virtual ICollection<GS_POS_T> GS_POS_T { get; set; }
        ...

GS_POS_C (sales)
        public long ID { get; set; }
        public long ID_T { get; set; }
        public Nullable<System.DateTime> OPEN_DATE { get; set; }
        ......    
        public virtual GS_POS_M GS_POS_M { get; set; }
        public virtual ICollection<GS_POS_C_PZ> GS_POS_C_PZ { get; set; }


GS_POS_C_PZ  (sale details)
        public long ID { get; set; }
        public long ID_C { get; set; }
        public Nullable<decimal> CANT { get; set; }
        public Nullable<decimal> PRICE { get; set; }
        public virtual GS_POS_C GS_POS_C { get; set; }
       ...

部分解决方案 我有下一个几乎可以工作的代码,但有两个问题:

1 。我不能包含在db.GS_POS_C的最终结果ID字段中

ExceptionMessage&#34;:&#34;转换为值类型&#39; System.Int64&#39;失败,因为具体化值为null。结果类型是通用的  参数或查询必须使用可空类型。&#34;

2 。我想将其转换为方法语法

from t in db.GS_POS_T
        join r in db.GS_POS_R on t.id_r equals r.id //it is inner join statement
        join c in db.GS_POS_C on t.id equals c.id_t  into ct
              from sub1 in ct.DefaultIfEmpty()  //it is left join statement
        join p in db.GS_POS_PZ on sub1.id equals p.id_c into psub1
              from sub2 in psub1.DefaultIfEmpty() //it is left join statement
              where t.activ == 1
        select new { t.id, t.name, rname = r.name,  sub2.cant, sub2.price } into x
        group x by new { id = x.id, name = x.name, rname = x.rname } into g
        select new
        {
            tid = g.Key.id,
            tname = g.Key.name,
            rname = g.Key.rname,
            sumpcantpprice = g.Sum(abc => abc.price * abc.cant)
        };

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

对于linq中的左外连接,您可以使用以下语法:

DefaultIfEmpty(new Model())

所以,这可能会给你一个想法,我在飞行中快速写下来,所以它可能不会从第一次尝试中消失。我不知道你的模型,所以替换linq语句中的模型并尝试一下:

    var result = from t in gs_pos_t

                        join r in gs_pos_r on t.id_r equals r.id

                        join c in gs_pos_c on t.id equals c.id_t into firstList from lt1 in firstList.DefaultIfEmpty(new Model1())

                        join p in gs_pos_pz onc.id equals p.id_c into secondList from lt2 in secondList.DefaultIfEmpty(new Model2())

                        where c.open_date != null

                        select new
                        {
                            t.id,
                            t.name,
                            r.name,
                            lt1.id == null ? 0 : 1
                        };

希望有所帮助