Запишите этот SQL-запрос в лямбда-выражение Entity Framework или другим способом. - PullRequest
0 голосов
/ 27 февраля 2019

db.DbEnquiryModules - как написать этот запрос в виде лямбда-выражения или linq?

SELECT  
    tenq.EnquiryID
    ,tenq.EnquiryNo
    ,tenq.CompanyID
    ,tenq.EnquiryDate
    ,tenq.ClientID
    ,tenq.Address
    ,tenq.ContactPerson
    ,tenq.Email
    ,tenq.Mobile
    ,tenq.Landline
    ,tenq.SourceID
    ,tenq.PriorityID
    ,tenq.AreaID
    ,tenq.status
    ,tenq.Remark
    ,tenq.IsDeleted
    ,tenq.CreatedDate
    ,tenq.CreatedBy
    ,tenq.ModifiedDate
    ,tenq.ModifiedBy
    ,Y.FollowupDate AS LastFollowup
    ,Y.NextFollowup AS NextFollowup
    ,srno2
INTO
    #tmp 
FROM
    tblEnquiryModule tenq
LEFT JOIN 
   (SELECT 
        ROW_NUMBER() OVER (PARTITION BY EnquiryModuleID ORDER BY FollowupId DESC) SRno2,
        * 
    FROM
        tblFollowup) Y ON Y.EnquiryModuleID = EnquiryID
                       AND Y.srno2 <=2  ----------Last followUp
WHERE
    tenq.CompanyID = @companyid


--

DELETE a
FROM #tmp a
JOIN #tmp b ON a.EnquiryID = b.EnquiryID
            AND b.srno2 = 2
WHERE a.srno2 = 1 

SELECT * FROM #tmp 

У меня есть две таблицы с запросом, и его запрос followup.above возвращает запрос с его последней датой отслеживания, если он присутствует, иследующая дата отслеживания

Моя сущность

public class DTOEnquiryModule
{   [Key]
    public int EnquiryID { get; set; }
    public string EnquiryNo { get; set; }
    public int CompanyID { get; set; }
    public DateTime? EnquiryDate { get; set; }
    public string Mobile { get; set; }
    public string Landline { get; set; }
    public string status { get; set; }
    public int? ModifiedBy { get; set; }}  

public class DTOFollowup
{
    [Key]
    public int FollowupId { get; set; }
    public int EnquiryModuleID { get; set; }
    [ForeignKey("EnquiryModuleID")]
    public DTOEnquiryModule EnquiryModule { get; set; }
    public DateTime FollowupDate { get; set; }
    public string FollowupRemark { get; set; }
    public DateTime? NextFollowup { get; set; }
    public string NextFollowupRemark { get; set; }
}

Таблица запросов

|EnquiryID|EnquiryNo|EnquiryDate            |status 
|1        |EN1      |2019-02-19 00:00:00.000|ongoing
|2        |EN2      |2019-02-20 00:00:00.000|ongoing
|3        |EN3      |2019-02-23 00:00:00.000|ongoing

Таблица отслеживания

FollowupId|EnquiryModuleID|FollowupDate           |FollowupRemark|NextFollowup 
1         |1              |2019-02-20 00:00:00.000|NA            |NULL
2         |2              |2019-02-21 00:00:00.000|NA            |2019-02-23 00:00:00.000
3         |2              |2019-02-23 00:00:00.000|NA            |NULL
4         |3              |2019-02-24 00:00:00.000|NA            |2019-02-26 00:00:00.000
5         |3              |2019-02-26 00:00:00.000|NA            |2019-02-28 00:00:00.000
6         |3              |2019-02-28 00:00:00.000|NA            |NULL

Я хочу ниже таблицы результатов

|EnquiryID|EnquiryNo|EnquiryDate            |status |NextFollowup           |LastFollowup
|1        |EN1      |2019-02-19 00:00:00.000|ongoing|NULL                   |2019-02-20 00:00:00.000
|2        |EN2      |2019-02-20 00:00:00.000|ongoing|2019-02-23 00:00:00.000|2019-02-21 00:00:00.000
|3        |EN3      |2019-02-23 00:00:00.000|ongoing|2019-02-28 00:00:00.000|2019-02-26 00:00:00.000

Когда я добавляю новое наблюдение, мне нужно обновить предыдущие данные о последующем наблюдении для ведения истории и получить последние наблюдения по идентификатору запроса.

Я хочу показать список запросов с последним и следующим наблюдениемдата

1 Ответ

0 голосов
/ 28 февраля 2019

Итак, у вас есть таблицы с Enquiries и FollowUps.Каждый Enquiry имеет ноль или более FollowUps, каждый FollowUp принадлежит ровно одному запросу, используя внешний ключ: прямое отношение один ко многим.

Если бы вы следовали первые соглашения о коде структуры сущностей, у вас были бы такие классы, как:

class Enquiry
{
    public int Id {get; set; }
    public string EnquiryNo { get; set; }
    public DateTime? EnquiryDate { get; set; }
    public string status { get; set; }
    ...

    // every Enquiry has zero or more FollowUps (one-to-many)
    public virtual ICollection<FollowUp> FollowUps {get; set;}
}

class FollowUp
{
    public int Id {get; set; }
    public DateTime FollowupDate { get; set; }
    ...

    // every FollowUp belongs to exactly one Enquiry, using foreign key
    public int EnquiryId {get; set;}
    public virtual Enquiry Enquiry {get; set;}
}

Для полноты DbContext:

class MyDbContext : DbContext
{
    public DbSet<Enquiry> Enquiries {get; set;}
    public DbSet<FollowUp> FollowUps {get; set;}
}

Поскольку я следовал соглашениям, это всеэта структура сущностей должна знать, чтобы обнаружить ваши таблицы, столбцы в ваших таблицах и связь между таблицами.Только если вам нужны разные идентификаторы, вам понадобятся атрибуты или свободный API. Важной частью этого является то, что я указываю один-ко-многим, используя виртуальные свойства

В структуре сущностей столбцы представлены не виртуальными свойствами;виртуальные свойства представляют отношения между таблицами (один-ко-многим, многие-ко-многим, ...)

Ваше требование: «Всякий раз, когда мне добавляют новое наблюдение, необходимо обновитьпредыдущая последующая информация ".

Я добавлен?необходимо обновить предыдущее наблюдение?Возможно, вам стоит поработать над вашими навыками по требованию.

Я думаю, что вы имели в виду следующее:

Требование Дайте мне (некоторые свойства) все Запросы, с его новейшей FollowUpDate иего новейшая, но единственная FollowupDate (которую по какой-то причине вы решаете назвать последней датой)

Если у запроса есть только одно последующее наблюдение, я хочу указать дату запроса и последующее обновление.Если в запросе нет последующих запросов, я хочу указать только дату запроса.

Таким образом, набором подходящих FollowUpdates является EnquiryDate + all FollowUpdates.Закажите их по убыванию даты и возьмите первые два.

var result = dbContext.Enquiries.Select(enquiry => new
{
    EnquiryId = enquiry.Id,
    EnquiryNo = enquiry.EnquiryNo,
    EnquiryDate = enquiry.EnquiryDate,
    Status = enquiry.Status,

    // For the followups: take the followUp dates as nullable DateTime
    // and add the EnquiryDate
    FollowUps = enquiry.FollowUps
        .Select(followUp => followUp.FollowUpdate)
        .Cast<DateTime?>()
        .Concat(new DateTime?[] {enquiry.EnquiryDate})

        // take the two newest ones; we don't want null values
        .Where(date => date != null)
        .OrderByDescending(date => date)
        .Take(2)
        .ToList(),
})

// move this to local process, so you can use FollowUps to get Next / Last
.AsEnumerable()
.Select(fetchedData => new
{
    EnquiryId = fetchedData.EnquiryId,
    EnquiryNo = fetchedData.EnquiryNo,
    EnquiryDate = fetchedData.EnquiryDate,
    Status = fetchedData.Status,

    // FollowUps are ordered in Descending order. FirstOrDefault is the newest!
    NextFollowUp = enquiry.FollowUps.FirstOrDefault(),
    LastFollowUp = enquiry.FollowUps.LastOrDefault(),
}

Платформа сущностей знает ваше отношение «один ко многим».Это переведет ваше использование ICollection в GroupJoin

При желании вы можете позволить вашей системе управления базами данных сделать выбор NextFollowUp и LastFollowUp.Количество передаваемых данных будет одинаковым, поэтому это не ускорит ваш процесс.

Некоторые люди не любят использовать virtual ICollection, чтобы получить «Запросы со своими ответами».Вы можете сделать GroupJoin самостоятельно:

result = dbContext.Enquiries.GroupJoin(dbContext.FollowUps,
    enquiry => enquiry.Id,           // from each enquiry take the primary key
    followUp => followUp.EnquiryId,  // from each followUp take the foreign key

    // result selection: use each enquiry with all its matching followUps to make a new
    (enquiry, followUpsOfThisEnquiry) => new
    {
        EnquiryId = enquiry.Id,
        ... etc.

Поддерживайте нормализацию своей базы данных

Вы решили добавить столбец DateTime NextFollowUp в свою базу данных.Это не хороший выбор.

Id | FollowUpDate | NextFollowUpDate
01 |  2019-02-13  |  2019-02-14
20 |  2020-02-29  |     null

Мне кажется, что FollowUp [20] - это следующий FollowUp из FollowUp 1 .Что произойдет, если я изменю дату FollowUp [20]:

Id | FollowUpDate | NextFollowUpDate
01 |  2019-02-13  |  2019-02-14
20 |  2019-02-14  |     null

Это все еще верно?Неужели [20] вдруг не следующий из [01]?Всякий раз, когда вы меняете дату, вы должны проверять все подписки, чтобы увидеть, указывает ли она на эту подписку.

А как насчет следующего:

Id | FollowUpDate | NextFollowUpDate
04 |  2019-02-13  |  2019-02-14
05 |  2019-02-14  |     null
06 |  2019-02-14  |     null

Кто следующий из [04]?

Имейте в виду, что продолжение идентифицируется по первичному ключу, а не по дате.Дата наблюдения может измениться.Однако это не меняет само продолжение.

Id | FollowUpDate | NextFollowUpId
04 |  2019-02-13  |      05
05 |  2019-02-20  |      06
06 |  2019-02-14  |     null

После введения вы можете смело изменять любое свойство FollowUp, кроме, конечно, его первичного ключа.Прежде чем вы решите ввести контекст «следующего наблюдения», вы должны сами подумать, что это такое: это следующий по дате?Тогда вам не нужен внешний ключ, вы можете заказать их по дате

...