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
我有两个查询表及其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
当我添加新的后续内容时,需要更新以前的维护历史记录的后续详细信息,并通过查询ID获取最新的后续跟进。
我想在最后一次跟进和下一个跟进日期显示查询列表
所以你有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和Follow Update。如果询问没有跟进,我只想要EnquiryDate。
因此,符合条件的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]是跟进qazxsw poi的下一个跟进。如果我更改FollowUp [20]的日期会发生什么:
1
这仍然是正确的吗? [20]突然不是[01]的下一个吗?每当您更改日期时,您都必须检查所有FollowUps以查看它是否指向此FollowUp。
以下是什么:
Id | FollowUpDate | NextFollowUpDate
01 | 2019-02-13 | 2019-02-14
20 | 2019-02-14 | null
谁是[04]的下一个?
请记住,跟进由其主键标识,而不是由其日期标识。跟进日期可能会改变。然而,这并没有改变后续行动本身。
Id | FollowUpDate | NextFollowUpDate
04 | 2019-02-13 | 2019-02-14
05 | 2019-02-14 | null
06 | 2019-02-14 | null
介绍之后,您可以安全地更改FollowUp的任何属性,当然除了它的主键。在您决定介绍“下一步跟进”的背景之前,您应该自己思考它是什么:它是下一个日期吗?然后您不需要外键,您可以按日期时间订购它们