簡體   English   中英

將此SQL查詢寫入Entity Framework lambda表達式或其他方式

[英]Write this SQL query to Entity Framework lambda expression or other way

db.DbEnquiryModules如何將此查詢編寫為lambda表達式或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 

我有兩個帶有查詢及其后續操作的表。上面的查詢返回查詢及其最后的跟蹤日期(如果存在)和下一個跟蹤日期

我的實體

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

每當我添加新的跟蹤記錄時,都需要更新以前的跟蹤記錄詳細信息以維護歷史記錄並通過查詢ID獲得最新的跟蹤記錄。

我想顯示上次跟進和下一次跟進日期的查詢清單

因此,您具有帶有“ 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(出於某種原因,您決定將其作為最后的日期)。

如果一個查詢只有一個跟進,則需要EnquiryDate和FollowUpdate。 如果查詢沒有后續行動,我只需要查詢日期。

因此,合格的FollowUpdates的集合是EnquiryDate +所有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 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的任何屬性,但其主鍵除外。 在決定介紹“下一次跟進”的上下文之前,您應該自己考慮一下它是什么:下一次更新嗎? 然后,您不需要外鍵,可以按日期時間排序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM