using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.AccRepository.Entities;
using Siger.Middlelayer.AccRepository.Repositories.Interface;
using Siger.Middlelayer.AccRepository.Request;
using Siger.Middlelayer.AccRepository.Response;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.Middlelayer.AccRepository.Repositories
{
    internal class SigerRoutingInStationRepository : AccRepositoryBase<SigerTrRoutingInStation>, ISigerRoutingInStation
    {
        private readonly ApiAccDbContext accDbContext;
        public SigerRoutingInStationRepository(ApiAccDbContext context) : base(context)
        {
            accDbContext = context;
        }

        public siger_project_product GetProductInfo(int projectid, string code)
        {
            return accDbContext.siger_project_product.FirstOrDefault(t => t.projectid == projectid && t.code == code && t.status == (int)RowState.Valid);
        }

        public IEnumerable<SigerTrRoutingInStation> GetDataList(int fromline, int toline, int projectid)
        {
            var routs =
                accDbContext.siger_tr_routing_instation.Where(q => q.status == (int)RowState.Valid && q.projectId == projectid);
            var query = from a in routs
                        join b in accDbContext.siger_project_level_section
                        on fromline equals b.parentid
                        join c in accDbContext.siger_project_level_section
                        on toline equals c.parentid
                        where b.title == c.title && a.Line == fromline
                        select new SigerTrRoutingInStation
                        {
                            ProductId = a.ProductId,
                            Line = toline,
                            Station = c.id,
                            ResultStatus = a.ResultStatus,
                            projectId = projectid
                        };

            var entities = query.OrderByDescending(q => q.id).AsNoTracking().ToList();
            return entities;
        }

        public IEnumerable<RoutingInStation> GetRoutingInList(string productid, int line, int station, int projectid)
        {
            var rowstate = (int)RowState.Valid;
            var routs =
                accDbContext.siger_tr_routing_instation.Where(q => q.status == (int)RowState.Valid && q.projectId == projectid);
            var query = from p in routs
                        join m in accDbContext.siger_project_level_section
                        on new { lineid = p.Line, projectids = projectid, rowstatus = rowstate }
                        equals new { lineid = m.id, projectids = m.projectid, rowstatus = m.status }
                        into linetemp
                        from m in linetemp.DefaultIfEmpty()
                        join q in accDbContext.siger_project_level_section
                        on new { stationid = p.Station, projectids = projectid, rowstatus = rowstate }
                        equals new { stationid = q.id, projectids = q.projectid, rowstatus = q.status }
                        into stationtemp
                        from q in stationtemp.DefaultIfEmpty()
                        join pi in accDbContext.siger_project_product
                        on new { productid = p.ProductId, projectids = projectid, rowstatus = rowstate }
                        equals new { productid = pi.code, projectids = pi.projectid, rowstatus = pi.status }
                        into pitemp
                        from pi in pitemp.DefaultIfEmpty()
                        join d in accDbContext.siger_tr_dict
                        on new { dkeys = p.ResultStatus, cats = AccDictCost.status, rowstatus = rowstate, projectids = projectid }
                        equals new { dkeys = d.dkey, cats = d.cat, rowstatus = d.status, projectids = d.projectId }
                        into dtemp
                        from d in dtemp.DefaultIfEmpty()
                        select new RoutingInStation
                        {
                            productid = p.ProductId,
                            productid_value = pi.code,
                            line = p.Line,
                            line_value = m.title,
                            station = p.Station,
                            station_value = q.title,
                            resultstatus = p.ResultStatus,
                            status_value = d.dval
                        };

            Expression<Func<RoutingInStation, bool>> productidExpression = q => true;
            if (!string.IsNullOrEmpty(productid) && productid != "0")
            {
                productidExpression = q => q.productid == productid;
            }
            Expression<Func<RoutingInStation, bool>> lineExpression = q => true;
            if (line > 0)
            {
                lineExpression = q => q.line == line;
            }
            Expression<Func<RoutingInStation, bool>> stationExpression = q => true;
            if (station > 0)
            {
                stationExpression = q => q.station == station;
            }
            var predicate = productidExpression.And(lineExpression).And(stationExpression);

            var entities = query.Where(predicate).AsNoTracking().ToList();
            return entities;
        }

        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="instations"></param>
        /// <param name="projectid"></param>
        /// <returns></returns>
        public CommonImportResult ImportRoutingInStation(IEnumerable<RoutingInStationTemplate> instations, int projectid)
        {
            var errors = new List<string>();
            var rowIndex = 1;
            foreach (var p in instations)
            {
                rowIndex++;
                var linemodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == p.line && t.projectid == projectid && t.status == (int)RowState.Valid);
                var stationmodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == p.station && t.projectid == projectid && t.status == (int)RowState.Valid);
                var dicts = accDbContext.siger_tr_dict.FirstOrDefault(t => t.dval == p.status && t.status == (int)RowState.Valid && t.cat == AccDictCost.status && t.projectId == projectid);
                var model = accDbContext.siger_tr_routing_instation.FirstOrDefault(t => t.Line.ToString() == p.line && t.Station.ToString() == p.station && t.ProductId == p.productid
                    && t.status == (int)RowState.Valid && t.projectId == projectid && t.ResultStatus == p.status);
                var product = accDbContext.siger_project_product.FirstOrDefault(t => t.code == p.productid && t.status == (int)RowState.Valid && t.projectid == projectid);
                var outs = accDbContext.siger_tr_routing_outstation.FirstOrDefault(t => t.ResultStatus == p.status && t.status == (int)RowState.Valid && t.projectId == projectid);

                if (linemodel == null)
                    errors.Add($"{rowIndex},{(int)RequestEnum.LineError}");
                if (outs == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.RoutingStatusNotFind}");
                }
                if (stationmodel == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.StationError}");
                }
                else
                {
                    if (outs != null && outs.Station == stationmodel.id)
                    {
                        errors.Add($"{rowIndex},{(int)RequestEnum.LastStationNotEqualCurrentStation}");
                    }
                }
                if (dicts == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.RoutingStatusNotFind}");
                }
                if (product == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.ProductidNotNull}");
                }
                var repeats = instations.Where(t => t.line == p.line && t.station == p.station && t.productid == p.productid && t.status == p.status);
                if (model != null || repeats.Count() > 1)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.RoutingInExist}");
                }
            }

            if (errors.Any())
            {
                return new CommonImportResult(0, string.Join(";", errors));
            }
            var entities = new List<SigerTrRoutingInStation>();
            foreach (var item in instations)
            {
                var linemodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == item.line && t.projectid == projectid && t.status == (int)RowState.Valid);
                var stationmodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == item.station && t.projectid == projectid && t.status == (int)RowState.Valid);
                var dicts = accDbContext.siger_tr_dict.FirstOrDefault(t => t.dval == item.status && t.status == (int)RowState.Valid && t.cat == AccDictCost.status && t.projectId == projectid);
                var product = accDbContext.siger_project_product.FirstOrDefault(t => t.code == item.productid && t.status == (int)RowState.Valid && t.projectid == projectid);
                if (linemodel != null && stationmodel != null && dicts != null)
                {
                    var outstation = new SigerTrRoutingInStation
                    {
                        Line = linemodel.id,
                        Station = stationmodel.id,
                        ResultStatus = dicts.dkey ?? "",
                        projectId = projectid,
                        ProductId = product.code ?? "",
                    };
                    entities.Add(outstation);
                }
            }
            try
            {
                accDbContext.siger_tr_routing_instation.AddRange(entities);
                accDbContext.SaveChanges();
                return new CommonImportResult(1, "1");
            }
            catch
            {
                throw;
            }
        }

        public IEnumerable<RoutingInStation> GetRoutingStations(int line, string productid, int projectid)
        {
            var rowstate = (int)RowState.Valid;
            var routs =
                accDbContext.siger_tr_routing_instation.Where(q => q.status == (int)RowState.Valid && q.projectId == projectid);
            var query = from p in routs
                        join m in accDbContext.siger_project_level_section
                        on new { lineid = p.Line, projectids = projectid, rowstatus = rowstate }
                        equals new { lineid = m.id, projectids = m.projectid, rowstatus = m.status }
                        into linetemp
                        from m in linetemp.DefaultIfEmpty()
                        join q in accDbContext.siger_project_level_section
                        on new { stationid = p.Station, projectids = projectid, rowstatus = rowstate }
                        equals new { stationid = q.id, projectids = q.projectid, rowstatus = q.status }
                        into stationtemp
                        from q in stationtemp.DefaultIfEmpty()
                        join pi in accDbContext.siger_project_product
                        on new { productid = p.ProductId, projectids = projectid, rowstatus = rowstate }
                        equals new { productid = pi.code, projectids = pi.projectid, rowstatus = pi.status }
                        into pitemp
                        from pi in pitemp.DefaultIfEmpty()
                        join d in accDbContext.siger_tr_dict
                        on new { dkeys = p.ResultStatus, cats = AccDictCost.status, rowstatus = rowstate, projectids = projectid }
                        equals new { dkeys = d.dkey, cats = d.cat, rowstatus = d.status, projectids = d.projectId }
                        into dtemp
                        from d in dtemp.DefaultIfEmpty()
                        join r in accDbContext.siger_tr_routing_outstation
                        on new { resultststus = p.ResultStatus, projectids = projectid, rowstatus = rowstate }
                        equals new { resultststus = r.ResultStatus, projectids = r.projectId, rowstatus = r.status }
                        into rtemp
                        from r in rtemp.DefaultIfEmpty()
                        select new RoutingInStation
                        {
                            id = p.id,
                            fromid = r.id,
                            productid = p.ProductId,
                            productid_value = pi.code,
                            line = p.Line,
                            line_value = m.title,
                            station = p.Station,
                            station_value = q.title,
                            resultstatus = p.ResultStatus,
                            status_value = d.dval,
                            result = r.EventNo.ToString(),
                            fromline = r.Line,
                            fromstation = r.Station,
                            nodeheight = p.nodeheight,
                            nodewidth = p.nodewidth,
                            locleft = p.locleft,
                            loctop = p.loctop,
                            bgcolor = p.bgcolor,
                            fromnodeheight = p.lastnodeheight,
                            fromnodewidth = p.lastnodewidth,
                            fromlocleft = p.lastlocleft,
                            fromloctop = p.lastloctop,
                            frombgcolor = p.lastbgcolor,
                        };

            var querys = from p in query
                         join m in accDbContext.siger_project_level_section
                            on new { lineid = p.fromline, projectids = projectid, rowstatus = rowstate }
                            equals new { lineid = m.id, projectids = m.projectid, rowstatus = m.status }
                            into linetemp
                         from m in linetemp.DefaultIfEmpty()
                         join q in accDbContext.siger_project_level_section
                         on new { stationid = p.fromstation, projectids = projectid, rowstatus = rowstate }
                         equals new { stationid = q.id, projectids = q.projectid, rowstatus = q.status }
                         into stationtemp
                         from q in stationtemp.DefaultIfEmpty()
                         join d in accDbContext.siger_tr_dict
                            on new { dkeys = p.result, cats = AccDictCostNoProjectId.eventno, rowstatus = rowstate }
                            equals new { dkeys = d.dkey, cats = d.cat, rowstatus = d.status }
                            into dtemp
                         from d in dtemp.DefaultIfEmpty()
                         select new RoutingInStation
                         {
                             id = p.id,
                             fromid = p.fromid,
                             productid = p.productid,
                             productid_value = p.productid_value,
                             line = p.line,
                             line_value = p.line_value,
                             station = p.station,
                             station_value = p.station_value,
                             resultstatus = p.resultstatus,
                             status_value = p.status_value,
                             result = p.result,
                             result_value = d.dval,
                             fromline = p.fromline,
                             fromline_value = m.title,
                             fromstation = p.fromstation,
                             fromstation_value = q.title,
                             nodeheight = p.nodeheight,
                             nodewidth = p.nodewidth,
                             locleft = p.locleft,
                             loctop = p.loctop,
                             bgcolor = p.bgcolor,
                             fromnodeheight = p.fromnodeheight,
                             fromnodewidth = p.fromnodewidth,
                             fromlocleft = p.fromlocleft,
                             fromloctop = p.fromloctop,
                             frombgcolor = p.frombgcolor,
                         };


            Expression<Func<RoutingInStation, bool>> productidExpression = q => true;
            if (!string.IsNullOrEmpty(productid))
            {
                productidExpression = q => q.productid == productid;
            }
            Expression<Func<RoutingInStation, bool>> lineExpression = q => true;
            if (line > 0)
            {
                lineExpression = q => q.line == line;
            }
            var predicate = productidExpression.And(lineExpression);

            var entities = querys.Where(predicate).OrderBy(t => t.line).OrderBy(t => t.station).AsNoTracking().ToList();
            return entities;
        }

        public IPagedCollectionResult<ResponseRoutingData> GetRoutingData(RequestRoutingConfig conditions, int pid)
        {
            Expression<Func<ResponseRoutingData, bool>> funcProduct = f => true;
            Expression<Func<ResponseRoutingData, bool>> funcLine = f => true;
            Expression<Func<ResponseRoutingData, bool>> funcStation = f => true;
            var query = from o in accDbContext.siger_tr_routing_outstation
                        join i in accDbContext.siger_tr_routing_instation on o.ResultStatus equals i.ResultStatus
                        join e in accDbContext.siger_tr_routing_eventno on o.EventNo equals e.EventNo
                        join pd in accDbContext.siger_project_product on i.ProductId equals pd.code into pdTemp
                        from p in pdTemp.DefaultIfEmpty()
                        join r in accDbContext.siger_project_product_route on i.ProcessId equals r.id into rTemp
                        from pr in rTemp.DefaultIfEmpty()
                        join cl in accDbContext.siger_project_level_section on i.Line equals cl.id
                        join cs in accDbContext.siger_project_level_section on i.Station equals cs.id
                        join prcs in accDbContext.siger_project_level_section on o.Station equals prcs.id
                        where o.projectId == pid && o.projectId == i.projectId && o.projectId==e.projectId &&
                        o.status == (int)RowState.Valid && i.status == (int)RowState.Valid
                        select new ResponseRoutingData
                        {
                            Id=i.id,
                            LineId=cl.id,
                            Line= cl.title,
                            StationId=cs.id,
                            Station=cs.title,
                            FromLineId = prcs.id,
                            FromStationId =prcs.id,
                            FromStation=prcs.title,
                            ProductCode=i.ProductId,
                            ProductName=p==null?"":p.name,
                            Process_Id=pr==null?0:pr.id,
                            Process_Seq=pr==null?0:pr.serialNumber,
                            Process_Name=pr==null?"":pr.name,
                            EventNo=e.EventNo,
                            Result=e.Descr,
                            ResultStatus=o.ResultStatus, 
                            productid=p==null?0:p.id
                        };
            if (!string.IsNullOrEmpty(conditions.ProductCode))
                funcProduct = f => f.ProductCode.Equals(conditions.ProductCode);
            if (conditions.Line != 0)
                funcLine = f => f.LineId.Equals(conditions.Line);
            if (conditions.ToStation != 0)
                funcStation = f => f.StationId.Equals(conditions.ToStation);
            var predicate = funcProduct.And(funcLine).And(funcStation);
            var count = query.Where(predicate).Count();
            var entities = query.Where(predicate).Skip((conditions.page - 1) * conditions.pagesize).Take(conditions.pagesize).ToList();
            return new PagedCollectionResult<ResponseRoutingData>(entities, count);
            //Expression<Func<ResponseRoutingData, bool>> funcProduct = f => true;
            //Expression<Func<ResponseRoutingData, bool>> funcLine = f => true;
            //Expression<Func<ResponseRoutingData, bool>> funcStation = f => true;
            //var query = from ri in accDbContext.siger_tr_routing_instation
            //            join rs in accDbContext.siger_tr_routing_outstation on ri.ResultStatus equals rs.ResultStatus
            //            join p in accDbContext.siger_project_product on ri.ProductId equals p.code into temp
            //            from pr in temp.DefaultIfEmpty()
            //            join pp in accDbContext.siger_project_process on ri.ProcessId equals pp.id
            //            join rse in accDbContext.siger_tr_routing_eventno on rs.EventNo equals rse.EventNo
            //            where rse.projectId.Equals(pid)
            //            && pp.ProjectId.Equals(pid)
            //            && rs.projectId.Equals(pid)
            //            && ri.status == (int)RowState.Valid
            //            && rs.status == (int)RowState.Valid
            //            && pp.status == (int)RowState.Valid
            //            && rse.status == (int)RowState.Valid
            //            select new ResponseRoutingData
            //            {
            //                ProductName = pr.name,
            //                ProductCode = pr.code,
            //                Process_Seq = pp.Process_Seq,
            //                Process_Name = pp.Process_name,
            //                LineId = ri.Line,
            //                StationId = ri.Station,
            //                FromStationId = rs.Station,
            //                FromLineId = rs.Line,
            //                EventNo = rs.EventNo,
            //                ResultStatus = ri.ResultStatus,
            //                Result = rse.Descr,
            //                ProcessType = pp.Process_Type
            //            };
            //if (!string.IsNullOrEmpty(conditions.ProductCode))
            //{
            //    funcProduct = f => f.ProductCode.Equals(conditions.ProductCode);
            //}
            //if (conditions.Line != 0)
            //{
            //    funcLine = f => f.LineId.Equals(conditions.Line);
            //}
            //if (conditions.ToStation != 0)
            //{
            //    funcStation = f => f.StationId.Equals(conditions.ToStation);
            //}
            //var predicate = funcProduct.And(funcLine).And(funcStation);
            //var count = query.Where(predicate).Count();
            //var entities = query.Where(predicate).Skip((conditions.page - 1) * conditions.pagesize).Take(conditions.pagesize).ToList();
            //return new PagedCollectionResult<ResponseRoutingData>(entities, count);
        }

        public CommonImportResult ImportRoutingData(IEnumerable<RoutingData> instations, int projectid)
        {
            var errors = new List<string>();
            var rowIndex = 1;
            foreach (var p in instations)
            {
                rowIndex++;
                var linemodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == p.Line && t.projectid == projectid && t.status == (int)RowState.Valid);
                var stationmodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == p.Station && t.projectid == projectid && t.status == (int)RowState.Valid);
                var product = accDbContext.siger_project_product.FirstOrDefault(t => t.code == p.ProductCode && t.status == (int)RowState.Valid && t.projectid == projectid);
                var fromstation = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == p.FromStation && t.projectid == projectid && t.status == (int)RowState.Valid);
                var resultmodle = accDbContext.siger_tr_routing_eventno.FirstOrDefault(t => t.Descr == p.Result && t.projectId == projectid && t.status == (int)RowState.Valid);
                var processtmodle = accDbContext.siger_project_product_route.FirstOrDefault(t => t.name == p.Process_Name && t.serialNumber == p.Process_Seq && t.productId == product.id && t.projectId == projectid && t.status == (int)RowState.Valid);

                if (linemodel == null)
                    errors.Add($"{rowIndex},{(int)RequestEnum.LineError}");
                if (stationmodel == null || fromstation == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.StationError}");
                }
                if (product == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.ProductidNotNull}");
                }
                if (resultmodle == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.EventNoNotFind}");
                }
                if (processtmodle == null)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.ProcessNotFind}");
                }
                var repeats = instations.Where(t => t.Line == p.Line && t.Station == p.Station && t.ProductCode == p.ProductCode && t.FromStation == p.FromStation && t.Result == p.Result);
                if (repeats.Count() > 1)
                {
                    errors.Add($"{rowIndex},{(int)RequestEnum.RoutingInExist}");
                }
                var indata = accDbContext.siger_tr_routing_instation.Where(t => t.projectId == projectid && t.status == (int)RowState.Valid && t.Station == stationmodel.id && t.ProductId.Equals(p.ProductCode));
                if (indata.Any())
                {
                    foreach (var item in indata)
                    {
                        var outModel = accDbContext.siger_tr_routing_outstation.FirstOrDefault(f => f.ResultStatus.Equals(item.ResultStatus) && f.Station.Equals(fromstation.id) && f.EventNo.Equals(resultmodle.EventNo));
                        if (outModel != null)
                        {
                            errors.Add($"{rowIndex},{(int)RequestEnum.RoutingInExist}");
                        }
                    }
                }
            }
            if (errors.Any())
            {
                return new CommonImportResult(0, string.Join(";", errors));
            }

            var inDatalist = new List<SigerTrRoutingInStation>();
            var outDatalist = new List<SigerTrRoutingOutStation>();
            foreach (var item in instations)
            {
                var product = accDbContext.siger_project_product.FirstOrDefault(t => t.code == item.ProductCode && t.status == (int)RowState.Valid && t.projectid == projectid);
                var linemodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == item.Line && t.projectid == projectid && t.status == (int)RowState.Valid);
                var stationmodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == item.Station && t.projectid == projectid && t.status == (int)RowState.Valid);
                var processtmodle = accDbContext.siger_project_product_route.FirstOrDefault(t => t.name == item.Process_Name && t.serialNumber == item.Process_Seq && t.productId == product.id && t.projectId == projectid && t.status == (int)RowState.Valid);
                var fromStationmodel = accDbContext.siger_project_level_section.FirstOrDefault(t => t.title == item.FromStation && t.projectid == projectid && t.status == (int)RowState.Valid);
                var resultmodle = accDbContext.siger_tr_routing_eventno.FirstOrDefault(t => t.Descr == item.Result && t.projectId == projectid && t.status == (int)RowState.Valid);
                var outdata = accDbContext.siger_tr_routing_outstation.FirstOrDefault(t => t.projectId == projectid && t.status == (int)RowState.Valid && t.Station == fromStationmodel.id&&t.EventNo.Equals(resultmodle.EventNo));

                string resultStatus = Guid.NewGuid().ToString();

                if (outdata != null)
                {
                    resultStatus = outdata.ResultStatus;
                }
                else
                {
                    //init _outStation
                    var outStationData = new SigerTrRoutingOutStation
                    {
                        Line = fromStationmodel.parentid,
                        EventNo = resultmodle.EventNo,
                        Station = fromStationmodel.id,
                        projectId = projectid,
                        status = (int)RowState.Valid,
                        ResultStatus = resultStatus,
                    };
                    outDatalist.Add(outStationData);
                }

                if (linemodel != null && stationmodel != null && processtmodle != null)
                {
                    //init _inStation
                    var instationData = new SigerTrRoutingInStation
                    {
                        Station = stationmodel.id,
                        projectId = projectid,
                        status = (int)RowState.Valid,
                        ResultStatus = resultStatus,
                        Line = linemodel.id,
                        ProcessId = processtmodle.id,
                        ProductId = item.ProductCode
                    };
                    inDatalist.Add(instationData);
                }
            }
            try
            {
                accDbContext.siger_tr_routing_instation.AddRange(inDatalist);
                accDbContext.siger_tr_routing_outstation.AddRange(outDatalist);
                accDbContext.SaveChanges();
                return new CommonImportResult(1, "1");
            }
            catch
            {
                throw;
            }
        }

        public IPagedCollectionResult<ResponseRoutingInStation> GetRoutingInStationPage(int projectId, int line, int station, string productId, int page = 1, int pagesize = 10)
        {
            Expression<Func<ResponseRoutingInStation, bool>> Funcat = f => true;
            Expression<Func<ResponseRoutingInStation, bool>> Funkey = f => true;
            Expression<Func<ResponseRoutingInStation, bool>> Funline = f => true;
            Expression<Func<ResponseRoutingInStation, bool>> Funproduct = f => true;
            //Expression<Func<ResponseRoutingInStation, bool>> Funstatus = f => true;
            if (line != 0)
                Funline = f => f.line == line;
            if (station != 0)
                Funkey = f => f.station == station;
            //if (eventno != 0)
            //    Funeventno = f => f.eventno == eventno;
            //if (!string.IsNullOrEmpty(status) && status != "0")
            //    Funstatus = f => f.status_value == status;

            var query = from i in accDbContext.siger_tr_routing_instation
                        join o in accDbContext.siger_tr_routing_outstation on i.ResultStatus equals o.ResultStatus
                        join e in accDbContext.siger_tr_routing_eventno on o.EventNo equals e.EventNo
                        join l in accDbContext.siger_project_level_section on i.Line equals l.id
                        join s in accDbContext.siger_project_level_section on i.Station equals s.id
                        join s2 in accDbContext.siger_project_level_section on o.Station equals s2.id
                        where i.projectId == projectId && i.status == (int)RowState.Valid
                        select new ResponseRoutingInStation
                        {

                            id = i.id,
                            line = i.Line,
                            line_value = l.title,
                            station = i.Station,
                            station_value = s.title,
                            outstation=o.Station,
                            outstation_value=s2.title,
                            productid=i.ProductId,
                            productid_value=i.ProductId,
                            eventno = e.EventNo,
                            eventno_value = e.Descr,
                            status_value = i.ResultStatus
                        };

            var predicate = Funcat.And(Funkey).And(Funline).And(Funproduct);
            var total = query.Count(predicate);
            var data = query.Where(predicate).Skip((page - 1) * pagesize).Take(pagesize).ToList();
            return new PagedCollectionResult<ResponseRoutingInStation>(data, total);
        }
    }
}
