使用Lambda连接5个表



我正在尝试使用lambda连接5个表。我想知道的是我做得是否正确,是否有更好的方法。任何建议都将不胜感激。

var myList = _context.Event
.Join(_context.EventHost,
e => e.EventHostId,
eh => eh.Id,
(e, eh) => new { Event = e, EventHost = eh })
.Join(_context.EventAddress,
eh => eh.EventHost.EventAddressID,
ea => ea.ID,
(eh, ea) => new { EventAddress = ea, EventHost = eh })
.Join(_context.OrderHeaderGroup,
ea => ea.EventHost.Event.Id,
ohg => ohg.EventId,
(ea, ohg) => new { EventAddress = ea, OrderHeaderGroup = ohg })
.Join(_context.OrderHeader,
ohg => ohg.OrderHeaderGroup.OrderHeaderGroupID,
oh => oh.OrderHeaderGroupID,
(oh, ohg) => new { OrderHeader = oh, OrderHeaderGroup = ohg })
.Select(c => new {
c.OrderHeader.OrderHeaderGroup.EventId,
c.OrderHeader.EventAddress.EventAddress.Name,
c.OrderHeader.EventAddress.EventAddress.Phone,
c.OrderHeader.EventAddress.EventAddress.Address1,
c.OrderHeader.EventAddress.EventAddress.Address2,
c.OrderHeader.EventAddress.EventAddress.City,
c.OrderHeader.EventAddress.EventAddress.Country,
c.OrderHeader.EventAddress.EventAddress.PostalCode,
c.OrderHeader.EventAddress.EventAddress.Email,
c.OrderHeader.EventAddress.EventHost.Event.ConsultantId,
c.OrderHeader.EventAddress.EventHost.Event.StartDate,
c.OrderHeader.EventAddress.EventHost.Event.EndDate,
}).Where(x => x.ContactId == contactId && x.StartDate >= newStartDate && x.EndDate <= newEndDate).ToList();

是的,使用查询语法,这是微软的建议:查看此处

在编译时,查询表达式根据C#规范中规定的规则转换为标准查询运算符方法调用。任何可以通过使用查询语法来表达的查询也可以通过使用方法语法来表达。但是,在大多数情况下,查询语法更可读、更简洁

from event in _context.Event
join eventHost in _context.EventHost 
on event.EventHostId equals eventHost.Id
join eventAddress in _context.EventAddress 
on eventHost.EventAddressId equals eventAddress.Id
// etc
select new {/*You new anonymous type here*/}

这里的问题不是优先的代码可读性。顺便说一句,我认为Lambda比Query表单可读性强得多。但那是因为我是一名程序员。

问题是,您正试图从SQL开发人员的角度进行编程。当LinqToEntities还是第一个东西的时候,我就这样做了,从SSMS等开始,我写了一个查询,然后把Transliteration转换成C#。

解决方案是使用ORM。如果您使用功能丰富的ORM,那么您应该有一个名为Navigation Properties的东西。这些已经为您提供了在Fluent映射中隐式或显式声明的隐式联接。因此,您不应该每次编写LINQ语句时都重新描述每个联接。

如果你信任这种语言并正确配置你的系统,你最终可能会得到这样的东西:

// This is not shortened, this should be the whole thing.
var myList = _context.OrderHeader
.Where(x => x.EventAddress.Something.ContactId == contactId 
&& x.EventAddress.Something.StartDate >= newStartDate 
&& x.EventAddress.Something.EndDate <= newEndDate)
.Select(c => new DetailEntityView(c)).ToList();

我还建议使用";查看";类。这些实体不是被配置为持久存在数据库的实体,而是类似于C#中的数据库视图。它们是较少使用的类,只传输数据。

public class DetailEntityView
{
public int EventId { get; set; }
public string Name { get; set; }
// ... etc
public DetailEntityView(OrderHeader c)
{
EventId = c.OrderHeaderGroup.EventId;
Name = c.EventAddress.EventAddress.Name;
// ... etc
}
}

现在,一些ORM的特色不如世界上的EF和NH。所以在这种情况下,我很抱歉你或你的团队选择了其他东西。

此外,您的所有联接都在ID上,这是应该的。但某些自定义查询联接在不受约束的字段上,如名称字段或其他值。在这种情况下,您确实需要将这些特定的联接添加到查询中。但是1。以及2.(为什么?和3.(然后你就可以做你在行动计划中做的事了。

最新更新