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获得最新的跟踪记录。
我想显示上次跟进和下一次跟进日期的查询清单
答案 0 :(得分:0)
因此,您有带有Enquiries
和FollowUps
的表。每个Enquiry
都具有零个或多个FollowUps
,每个FollowUp
都完全属于一个“查询”,使用外键:直接的一对多关系。
如果您遵循entity framework code first conventions,,您将拥有类似的课程:
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
在我看来,跟进[20]是跟进1的下一个跟进。如果我更改随访日期[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的任何属性,当然,其主键除外。在决定介绍“下一次跟进”的上下文之前,您应该自己考虑一下它是什么:下一次更新吗?然后,您不需要外键,可以按日期时间排序