简体   繁体   English

将此SQL查询写入Entity Framework lambda表达式或其他方式

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

db.DbEnquiryModules - how to write this query as a lambda expression or linq? 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 

I have two tables with enquiry and its followup.above query returns enquiry with its last followup date if present and next followup date 我有两个带有查询及其后续操作的表。上面的查询返回查询及其最后的跟踪日期(如果存在)和下一个跟踪日期

My entity 我的实体

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; }
}

Enquiry Table 查询表

|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

Followup table 随访表

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

I want below result table 我想要下面的结果表

|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

When ever i am added new followup, need to update previous follow up details for maintain history and get latest followup by enquiry id. 每当我添加新的跟踪记录时,都需要更新以前的跟踪记录详细信息以维护历史记录并通过查询ID获得最新的跟踪记录。

I want to show enquiry listing with last followup and next followup date 我想显示上次跟进和下一次跟进日期的查询清单

So you have tables with Enquiries and FollowUps . 因此,您具有带有“ Enquiries和“ FollowUps表。 Every Enquiry has zero or more FollowUps , every FollowUp belongs to exactly one `Enquiry, using a foreign key: A straightforward one-to-many relation. 每个Enquiry都具有零个或多个FollowUps ,每个FollowUp使用一个外键完全属于一个“查询”:一个直接的一对多关系。

If you'd followed the entity framework code first conventions, you would have had classes like: 如果您遵循实体框架代码优先约定,那么您将拥有类似以下的类:

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;}
}

For completeness the DbContext: 为了完整起见,DbContext:

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

Because I followed the conventions, this is all that entity framework needs to know to detect your tables, the columns in your tables and the relation between the tables. 因为我遵循了约定,所以这是实体框架检测表,表中的列以及表之间的关系所需了解的所有信息。 Only if you want different identifiers you'll need Attributes or fluent API. 仅当您需要其他标识符时,才需要属性或流利的API。 The important part of this is that I specify the one-to-many by using virtual properties 重要的部分是我使用虚拟属性指定了一对多

In entity framework the columns are represented by the non-virtual properties; 在实体框架中,列由非虚拟属性表示。 the virtual properties represent the relations between the tables (one-to-many, many-to-many, ...) 虚拟属性表示表之间的关系(一对多,多对多,...)

Your requirement: "When ever i am added new followup, need to update previous follow up details". 您的要求:“每当我添加新的跟进时,都需要更新以前的跟进详细信息”。

I am added? 我被加了吗? need to update previous follow up? 需要更新以前的跟进吗? Maybe you should work on your requirement skills. 也许您应该研究自己的需求技能。

I think you meant the following: 我认为您的意思是:

Requirement Give me (some properties of) all Enquiries, with its newest FollowUpDate and its newest-but-one FollowupDate (which for some reason you decide to call the last date). 要求给我(所有查询的属性),以及最新的FollowUpDate和最新但仅一个的FollowupDate(出于某种原因,您决定将其作为最后的日期)。

If an Enquiry has only one Followup, I want the EnquiryDate and the FollowUpdate. 如果一个查询只有一个跟进,则需要EnquiryDate和FollowUpdate。 If the Enquiry has no followups, I only want the EnquiryDate. 如果查询没有后续行动,我只需要查询日期。

So the collection of eligible FollowUpdates is the EnquiryDate + all FollowUpdates. 因此,合格的FollowUpdates的集合是EnquiryDate +所有FollowUpdates。 Order them by Descending date and take the first two. 按降序排列它们并取前两个。

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(),
}

Entity framework knows your one-to-many relation. 实体框架知道您的一对多关系。 It will translate your usage of the ICollection into a GroupJoin 它将您对ICollection的用法转换为GroupJoin

If desired you can let your database management system do the selection of NextFollowUp and LastFollowUp. 如果需要,您可以让数据库管理系统选择NextFollowUp和LastFollowUp。 The number of transferred data will be the same, so this won't speed up your process. 传输的数据数将相同,因此不会加快处理速度。

Some people don't like to use the virtual ICollection to get the "Enquiries with their Followup's". 有些人不喜欢使用virtual ICollection来获取“跟进他们的询问”。 You can do the GroupJoin yourself: 您可以自己加入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.

Keep your database normalized 保持数据库规范化

You decided to add a DateTime column NextFollowUp in your database. 您决定在数据库中添加DateTime列NextFollowUp。 This is not a good choice. 这不是一个好选择。

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

It seems to me that FollowUp [20] is the next FollowUp of FollowUp 1 . 在我看来,FollowUp [20]是FollowUp 1的下一个FollowUp。 What happens if I change the date of FollowUp [20]: 如果我更改随访日期[20],会发生什么:

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

Is this still correct? 这还正确吗? Is [20] suddenly not the next of [01]? [20]突然不是[01]的下一个吗? Whenever you change a date you'll have to check all FollowUps to see if it points to this FollowUp. 每当您更改日期时,都必须检查所有后续活动,以查看其是否指向此后续活动。

And what about the following: 以及以下内容:

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

Who is the Next of [04]? 谁是[04]下一位?

Keep in mind that a followup is identified by its primary key, not by its date. 请记住,后续操作是通过主键而不是日期来标识的。 The date of a followup might change. 随访日期可能会改变。 However this doesn't change the followup itself. 但这并不会改变后续行动本身。

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

After introducing you can safely change any property of the FollowUp, except of course its primary key. 引入后,您可以安全地更改FollowUp的任何属性,但其主键除外。 Before you decide to introduce the context of a "next follow up" you should think for yourself what it is: is it the next in date? 在决定介绍“下一次跟进”的上下文之前,您应该自己考虑一下它是什么:下一次更新吗? Then you don't need a foreign key, you can order them by datetime 然后,您不需要外键,可以按日期时间排序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM