Sql server 对Lambda表达式C的SQL查询#
SQL查询:Sql server 对Lambda表达式C的SQL查询#,sql-server,entity-framework,linq,lambda,Sql Server,Entity Framework,Linq,Lambda,SQL查询: SELECT M.MailItemId, m.Subject, ISNULL(m.SendCC, ''), ISNULL(attachments.counter, 0) Counters, M.CreationDate FROM MailItem AS M LEFT OUTER JOIN ( SELECT MailItemId, COUNT(MailItemId) counter FROM Attachment Group By MailItemId ) AS at
SELECT M.MailItemId, m.Subject, ISNULL(m.SendCC, ''), ISNULL(attachments.counter, 0) Counters, M.CreationDate
FROM MailItem AS M
LEFT OUTER JOIN (
SELECT MailItemId, COUNT(MailItemId) counter
FROM Attachment Group By MailItemId
) AS attachments ON M.MailItemId = attachments.MailItemId
有两种模式:邮件项目和附件。
MailItemId是MailItem中的主键,是附件模型中的外键。
要将上述查询转换为lambda表达式。因此您有一个包含
邮件项的表和一个包含附件的表。在邮件项目
和附件
之间有一个简单的一对多关系:每个邮件项目
都有零个或多个附件
,每个附件
都只属于一个邮件项目
,即外键所指的邮件项目
通常,人们想要“带有附件的邮件”,他们不想要左外连接:
- 邮件项目1及附件A、C
- 邮件项目2及附件B、D、F
- 无附件的邮件项目3
- 邮件项目4及附件E
另一方面,您似乎更喜欢以下结果:
MailItem Attachment
1 A
2 B
1 C
3 <null>
4 E
2 D
2 F
左外连接
使用虚拟ICollections
如果您遵循了实体框架约定,您将拥有类似于以下内容的类:
class MailItem
{
public int Id {get; set; }
...
// every MailItem has zero or more Attachments (one-to-many)
public virtual ICollection<Attachment> Attachments {get; set;}
}
class Attachment
{
public int Id {get; set; }
...
// every Attachment belongs to exactly one MailItem, using foreign key:
public int MailItemId {get; set;}
public virtual MailItem MailItem {get; set;}
}
实体框架知道这种关系,并将为您执行正确的(组)连接
我觉得这看起来比GroupJoin更自然,无论后面是否跟有selectMany,请不要撤消编辑。。。没有格式化就无法描述。到目前为止,你用Linq做了什么尝试?向我们展示您的代码和实体模型等。。
var result = dbContext.MailItems.GroupJoin(dbContext.Attachments,
mailitem => mailItem.MailItemId,
attachment => attachment.MailItemId,
(mailItem, attachmentsOfThisMailItem) => new
{
MailItem = mailItem,
Attachments = attachmentsOfThisMailItem,
})
// make it a left outer join, using SelectMany
.SelectMany(groupJoinResult => groupJoinResult.Attachments,
(groupJoinResult, attachment) => new
{
MailId = groupJoinResult.MailItem.Id,
Sender = groupJoinResult.MailItem.Sender,
...
AttachmentId = attachment.Id,
Format = attachment.Format,
...
});
class MailItem
{
public int Id {get; set; }
...
// every MailItem has zero or more Attachments (one-to-many)
public virtual ICollection<Attachment> Attachments {get; set;}
}
class Attachment
{
public int Id {get; set; }
...
// every Attachment belongs to exactly one MailItem, using foreign key:
public int MailItemId {get; set;}
public virtual MailItem MailItem {get; set;}
}
var mailItemsWithTheirAttachments = dbContext.MailItems.Select(mailItem => new
{
Id = mailItem.Id,
Sender = mailItem.Sender,
...
Attachments = mailItem.Attachments
.Where(attachment => ....) // only if you don't want all Attachments
.Select(attachment => new
{
Id = attachment.Id,
...
})
.ToList(),
});