Linq Concat优化

时间:2015-12-10 10:08:10

标签: c# linq

我目前正在尝试从三个不同的表中提取结果并将它们合并到一个列表中,如此...

var accountLogs = Context.AccountLogs.Where(s => s.Timestamp > fromDate).Select(s => new LogSummaryDto()
{
    UserId = s.User.Id,
    DisplayName = s.User.DisplayName
});

var spellLogs = Context.SpellLog.Where(s => s.Timestamp > fromDate).Select(s => new LogSummaryDto()
{
    UserId = s.User.Id,
    DisplayName = s.User.DisplayName
});
var generalLogs = Context.Log.Where(s => s.Timestamp > fromDate).Select(s => new LogSummaryDto()
{
    UserId = s.User.Id,
    DisplayName = s.User.DisplayName
}); 

var m1 = accountLog.Concat(spellLogs);
var m2 = m1.Concat(generalLogs).toList();

但是,我确信必须有一些方法使用linq这样做是一个查询,任何想法/指针?

4 个答案:

答案 0 :(得分:1)

您可以提前使用Concat,并一次过滤所有内容,如下所示:

var res = Context.AccountLogs.Select(s => new {
        s.TimeStamp
    ,   s.User.Id
    ,   s.User.DisplayName
    }).Concat(Context.SpellLog.Select(s => new {
        s.TimeStamp
    ,   s.User.Id
    ,   s.User.DisplayName
    })).Concat(Context.Log.Select(s => new {
        s.TimeStamp
    ,   s.User.Id
    ,   s.User.DisplayName
    }))
    // Selects / Concats above provide uniform structure
    // on which to apply the common Where clause
    .Where(s => s.TimeStamp > fromDate)
    .Select(s => new LogSummaryDto() {
        UserId = s.User.Id
    ,   DisplayName = s.User.DisplayName
    });

答案 1 :(得分:1)

您可以将LINQ逻辑提取到您自己的" LINQ运算符"中。这需要Context.AccountLogsContext.SpellLogContext.Log来实现相同的接口。让我们说他们都实现ILog,例如:

public interface ILog {
    User User { get; }
    DateTime Timestamp { get; }
}

然后您可以像这样实现自己的ExtractSummaryDtos

public static class LogSummaryDtoExtensions {
    public static IEnumerable<LogSummaryDto> ExtractSummaryDtos(this IEnumerable<ILog> logs, DateTime fromDate) {
        return logs.Where(s => s.Timestamp > fromDate).Select(s => new LogSummaryDto {
            UserId = s.User.Id,
            DisplayName = s.User.DisplayName
        });
    }
}

现在你可以像这样构建你的列表:

var m3 = AccountLogs.ExtractSummaryDtos(fromDate)
            .Concat(SpellLogs.ExtractSummaryDtos(fromDate))
            .Concat(Logs.ExtractSummaryDtos(fromDate));

答案 2 :(得分:0)

var m2 = new List<IEnumerable<dynamic>> {AccountLogs, SpellLogs, Logs}
    .SelectMany(x => x.Where(y => y.Timestamp > fromDate).Select(s => new LogSummaryDto {
        UserId = s.User.Id,
        DisplayName = s.User.DisplayName
    }));

答案 3 :(得分:-1)

您可以使用union:

var logs = ((
from s in Context.AccountLogs
where s.TimeStamp > fromDate 
select new {
UserId = s.User.Id,
DisplayName = s.User.DisplayName
})
.Union(
from s in Context.SpellLog
where s.TimeStamp > fromDate
select new {
UserId = s.User.Id,
DisplayName = s.User.DisplayName
})
.Union(
from s in Context.Log
where s.TimeStamp > fromDate
select new
{
UserId = s.User.Id,
DisplayName = s.User.DisplayName
})).ToList();