2013-05-02 2 views
0

У меня есть два IEnumerables. Один содержит даты, другой - данные.Как добавить значения null по умолчанию в объявлении объединения Linq

DateTime start = DateTime.Today.AddDays(-21); 

var dates = Enumerable.Range(0, 21).Select(n => start.AddDays(n)).ToArray(); 

var data = MyClass.Data.Select(x => new { Date = x.Date, Views = x.Count }); 

Я пытаюсь построить таблицу, которая показывает Views на данный день. Однако данные содержат некоторые пробелы. Как написать запрос linq, который соединяет два набора, и возвращает номер Views, если он присутствует, или 0, когда в данных нет соответствующего объекта?

Я могу сделать это старомодным способом с заявлениями foreach, но я хотел бы знать, как это сделать в Linq.

+2

У вас есть пример вывод, который вы хотели бы достичь? – LukeHennerley

+0

Что вы подразумеваете под «данными, содержащими некоторые пробелы» –

+0

@CodeIgnoto на вопрос теперь ответ, но я имел в виду, что данные не будут содержать соответствующее значение для всех дат, сгенерированных, так как в некоторые дни не было бы представлений. – roryok

ответ

1

Не уверен, что я полностью понял ваш question.If вы хотите создать список дней, который имеет по крайней мере один взгляды, то это будет получить работу.

DateTime start = DateTime.Today.AddDays(-21); 

//Sample view data 
var viewsData = new[] {new {id = "id", date = new DateTime(2013, 4, 12), views = 25}}; 

var dates = Enumerable.Range(0, 21) 
         .Select(d => start.AddDays(d)) 
         .Select(n => new 
             { 
             Day = n, 
             views =viewsData.Any(x => x.date == n) 
             ? viewsData.FirstOrDefault(v => v.date == n).views 
             : 0 
         }); 

Нулевой заполняются для дней, не имеющий вида на

+0

классно, не понял, я мог бы использовать условный оператор в новом утверждении. – roryok

+0

Очень неэффективно. Для каждой даты она объединяет всю коллекцию, чтобы определить, существует ли она, затем она снова петлиет ее, чтобы найти элемент. «Присоединение» намного [более эффективно] (http://stackoverflow.com/questions/5551264/why-is-linq-join-so-much-faster-than-linking-with-where). –

1

Это должно работать:

var data = from day in Enumerable.Range(0, 21).Select(n => start.AddDays(n)) 
      join d in MyClass.Data.Select(x => new { Date = x.Date, Views = x.Count }) 
      on day equals d.Date into gj 
      from dd in gj.DefaultIfEmpty() 
      select new { Date = day, Views = dd == null ? 0 : dd.Views }; 

Это возвращает видовой номер, когда есть один в данный день и 0 в противном случае.

How to: Perform Left Outer Joins

+0

Дальность - это действительно путь. – Serge