【问题标题】:Making the LINQ projection generic使 LINQ 投影通用
【发布时间】:2019-12-15 08:51:55
【问题描述】:

我有一个 LINQ 可以访问具有大型数据集的表,因此此查询对性能至关重要。我还希望对过滤后的数据集进行动态排序,因此我使用 LINQ 扩展通过在运行时传递排序列来进行排序。

由于遇到性能问题,我在排序后进行数据投影(查询如下)。因此,我必须在 OrderBy 和 OrderByDescending 扩展中重复投影。有没有办法提取投影以减少重复代码?

这是我的代码: 从源表中过滤数据 -

    var allOrderEntries = (from l in context.Orders
            where (branches.Count == 0 || branches.Contains(l.BranchId)) 
                && l.IsActive && !l.IsArchived 
                && (l.PreferredLanguage.LanguageKey == languageKey string.IsNullOrEmpty(languageKey))
                && (string.IsNullOrEmpty(searchText) || (l.FirstName == searchText || l.LastName == searchText || l.Notes == searchText || l.AccountNumber == searchText))
            select l;

这将返回一个 IQueryable,然后我将其传递给 OrderBy 扩展。这就是我想要解决的投影重复问题。

if (sortInfo.SortDirection == Common.Enum.SortDirection.Ascending)
                orderedList = allOrderEntries.OrderBy(sortInfo.SortColumn).Skip(pageInfo.Skip).Take(pageInfo.PageSize).Select(data => new OrderEntryDetailsDto
                {
                    Id = data.OrderId.ToString(),
                    AccountNumber = accountNumber.Mask(data.AccountNumber),
                    FirstName = data.FirstName,
                    LastName = data.LastName,
                    ServicesRequested = data.ServicesRequested, //string.Join(",", data.ServicesRequested.Select(s=> s.ServiceName).ToArray()),
                    PersonRequested = data.UserRequested != null ? data.UserRequested.FirstName + " " + data.UserRequested.LastName : data.GroupRequested != null ? data.GroupRequested.GroupName : string.Empty,
                    Notes = data.Notes ?? string.Empty,
                    WaitTime = string.Format("{0:hh\\:mm\\:ss}", (TimeSpan)(DateTime.UtcNow - data.AddedTime)),
                    Type = data.FkAppointmentId == null ? "Walk-In" : (from a in context.Appointments where a.AppointmentId == data.FkAppointmentId select a).Single().AppointmentStatus.AppointmentStatusName.ToString()           
                }).ToList();
            else
                orderedList = allOrderEntries.OrderByDescending(sortInfo.SortColumn).Skip(pageInfo.Skip).Take(pageInfo.PageSize).Select(data => new OrderEntryDetailsDto
                {
                    Id = data.OrderId.ToString(),
                    AccountNumber = accountNumber.Mask(data.AccountNumber),
                    FirstName = data.FirstName,
                    LastName = data.LastName,
                    ServicesRequested = data.ServicesRequested, //string.Join(",", data.ServicesRequested.Select(s=> s.ServiceName).ToArray()),
                    PersonRequested = data.UserRequested != null ? data.UserRequested.FirstName + " " + data.UserRequested.LastName : data.GroupRequested != null ? data.GroupRequested.GroupName : string.Empty,
                    Notes = data.Notes ?? string.Empty,
                    WaitTime = string.Format("{0:hh\\:mm\\:ss}", (TimeSpan)(DateTime.UtcNow - data.AddedTime)),
                    Type = data.FkAppointmentId == null ? "Walk-In" : (from a in context.Appointments where a.AppointmentId == data.FkAppointmentId select a).Single().AppointmentStatus.AppointmentStatusName.ToString()   
                }).ToList();

所以我想重新做 Select 部分,这是重复的,最好的方法是什么?

【问题讨论】:

  • 您不需要重新进行选择部分,只需在allOrderEntries 中再次等同于查询,因为您没有更改其类型/实体。根据您的情况,执行orderby, orderbydescending, skip, take 或添加where。然后在条件之后,执行.Select(), ToList(), First()。您可以在下面查看我的答案。

标签: linq extension-methods projection


【解决方案1】:

试试这个,因为它是IQueryable

if (sortInfo.SortDirection == Common.Enum.SortDirection.Ascending)
{     
    allOrderEntries = allOrderEntries.OrderBy(sortInfo.SortColumn)
                     .Skip(pageInfo.Skip).Take(pageInfo.PageSize).AsQueryable();
}
else
{
    allOrderEntries = allOrderEntries.OrderByDescending(sortInfo.SortColumn)
                     .Skip(pageInfo.Skip).Take(pageInfo.PageSize).AsQueryable();
}


var orderedList = allOrderEntries.Select(data => new OrderEntryDetailsDto
            {
                Id = data.OrderId.ToString(),
                AccountNumber = accountNumber.Mask(data.AccountNumber),
                FirstName = data.FirstName,
                LastName = data.LastName,
                ServicesRequested = data.ServicesRequested, //string.Join(",", data.ServicesRequested.Select(s=> s.ServiceName).ToArray()),
                PersonRequested = data.UserRequested != null ? data.UserRequested.FirstName + " " + data.UserRequested.LastName : data.GroupRequested != null ? data.GroupRequested.GroupName : string.Empty,
                Notes = data.Notes ?? string.Empty,
                WaitTime = string.Format("{0:hh\\:mm\\:ss}", (TimeSpan)(DateTime.UtcNow - data.AddedTime)),
                Type = data.FkAppointmentId == null ? "Walk-In" : (from a in context.Appointments where a.AppointmentId == data.FkAppointmentId select a).Single().AppointmentStatus.AppointmentStatusName.ToString()   
            }).ToList();

【讨论】:

  • 谢谢!应该考虑一下!
猜你喜欢
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多