как вычесть предыдущее значение записи из текущего значения в рамках сущности, используя linq - PullRequest
0 голосов
/ 06 апреля 2020

Я получаю кумулятивные значения в таблице базы данных, но мне нужно инкрементное значение в одном столбце, так что мне нужно вычесть из предыдущей записи. Нужно вычесть из kwh. KWH_I = текущая квтч - предыдущая квтч получение ошибки -

«ExceptionMessage»: «Операция не может быть завершена из-за удаления DbContext.»,

просмотр модели

 public partial class Total_Power
    {
        public int A_id { get; set; }
        public string DeviceImei { get; set; }
        public Nullable<System.DateTime> DeviceTimeStamp { get; set; }
        public Nullable<double> KWH { get; set; }
        public Nullable<double> KWH_I { get; set; }

    }

code

 [HttpGet]
    [Route("Trans/TotalPowerV2/all/{imei}/{StartDate}/{EndDate}")]
    public async Task<IHttpActionResult> GetDatewiseTotal_PowerData_v2(string imei, string StartDate, string EndDate)
    {
        DateTime sd = Convert.ToDateTime(StartDate);
        DateTime ed = Convert.ToDateTime(EndDate);
        using (TransformerEntities entities = new TransformerEntities())
        {
            try
            {
                var response = from locationLog in entities.Total_Power
                .Where(s => s.DeviceImei == imei && s.DeviceTimeStamp >= sd && s.DeviceTimeStamp <= ed)
                .OrderByDescending(t => t.DeviceTimeStamp)
                                   // get the previous log from locationLog                       
                               let prevLog = entities.Total_Power
                                     .Where(s => s.DeviceImei == imei
                                             && s.DeviceTimeStamp >= sd
                                             && s.DeviceTimeStamp <= ed
                                             && s.DeviceTimeStamp <= locationLog.DeviceTimeStamp
                                             && s.A_id != locationLog.A_id)
                                      .OrderByDescending(s => s.DeviceTimeStamp)
                                      .FirstOrDefault()
                               orderby locationLog.DeviceTimeStamp
                               select new
                               {
                                   A_id = locationLog.A_id,
                                   DeviceImei = locationLog.DeviceImei,
                                   DeviceTimeStamp = locationLog.DeviceTimeStamp,
                                   KWH = locationLog.KWH,
                                   prevId = prevLog != null ? prevLog.A_id : -1,
                                   KWH_I = prevLog != null ? locationLog.KWH - prevLog.KWH : 0
                               };

                return Ok(response.ToList());
            }
            catch (Exception Ex)
            {
                return BadRequest("Sorry Error Found!!!");
            }
        }
    }

требование

    [
    {
        "A_id": 943137,
        "DeviceImei": "613",
        "DeviceTimeStamp": "2020-03-24T23:45:18",
        "KWH": 326003.1,
        "KWH_I": 11,
    },
    {
        "A_id": 943133,
        "DeviceImei": "613",
        "DeviceTimeStamp": "2020-03-24T23:30:18",
        "KWH": 325992.4,
        "KWH_I": 0,
          }
]

1 Ответ

0 голосов
/ 06 апреля 2020

Хорошо, обычно в SQL мы будем использовать LEAD / LAG оконные функции для выполнения таких функций. Но поскольку нет простого способа использовать LEAD / LAG в Entity Framework без использования библиотеки, такой как MoreLinq или Linq2DB, я предложил следующее решение в одном из моих существующих проектов.

List<TestModel> logs = new List<TestModel>();
  logs.Add(new TestModel() { A_id = 1, DeviceImei = "234", DeviceTimeStamp = DateTime.Now.AddDays(-2), KWH = 50 });
  logs.Add(new TestModel() { A_id = 2, DeviceImei = "234", DeviceTimeStamp = DateTime.Now.AddDays(-2).AddSeconds(2), KWH = 50 });
  logs.Add(new TestModel() { A_id = 3, DeviceImei = "234", DeviceTimeStamp = DateTime.Now.AddDays(-2).AddSeconds(3), KWH = 650 });
  logs.Add(new TestModel() { A_id = 4, DeviceImei = "234", DeviceTimeStamp = DateTime.Now.AddDays(-2).AddSeconds(4), KWH = 90 });
  logs.Add(new TestModel() { A_id = 5, DeviceImei = "234", DeviceTimeStamp = DateTime.Now.AddDays(-2).AddSeconds(5), KWH = 20 });
  logs.Add(new TestModel() { A_id = 6, DeviceImei = "234", DeviceTimeStamp = DateTime.Now.AddDays(-2).AddSeconds(6), KWH = 50 });

string imei = "234";
DateTime sd = DateTime.Today.AddDays(-3);
DateTime ed = DateTime.Today.AddDays(1);


var response = from locationLog in logs
                    .Where(s => s.DeviceImei == imei && s.DeviceTimeStamp >= sd && s.DeviceTimeStamp <= ed)
                    .OrderBy(t => t.DeviceTimeStamp)

             // get the previous log from locationLog                       
             let prevLog = logs
                    .Where(s => s.DeviceImei == imei
                           && s.DeviceTimeStamp >= sd
                           && s.DeviceTimeStamp <= ed
                           && s.DeviceTimeStamp <= locationLog.DeviceTimeStamp
                           && s.A_id != locationLog.A_id)
                    .OrderByDescending(s => s.DeviceTimeStamp)
                    .FirstOrDefault()

        orderby locationLog.DeviceTimeStamp
                           select new
                           {
                               A_id = locationLog.A_id,
                               DeviceImei = locationLog.DeviceImei,
                               DeviceTimeStamp = locationLog.DeviceTimeStamp,
                               KWH = locationLog.KWH,
                               prevId = prevLog != null ? prevLog.A_id : -1,
                               KWH_I = prevLog != null ? locationLog.KWH - prevLog.KWH : 0
                           };

При переводе на SQL это будет означать запрос OUTER APPLY SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...