5

Mam zapytanie, które powinno zwrócić sumę całkowitej liczby godzin podanych dla bieżącego tygodnia. Ten kod poniżej zwraca poprawną liczbę godzin, ale nie dla konkretnego użytkownika w bazie danych.Zapytanie Linq, pomieszane, gdzie klauzula w metodzie

public int reportedWeekTime(int currentWeek, string username) 
     { 
      var totalTime = (from u in context.Users 
         from r in context.Reports 
         from w in context.Weeks 
         from d in context.Days 
         where u.Id == r.UserId && r.weekNr.Equals(currentWeek) && r.Id == w.ReportId && w.DayId == d.Id 
         select d.Hour).DefaultIfEmpty(0).Sum(); 
      return totalTime; 
     } 

Pierwsza metoda zwraca liczbę 24, która jest poprawna, ale jak powiedziałem, nie dla konkretnego użytkownika.

Próbuję to zrobić, ale daje mi to 0 w zamian. Co ja robię źle?

public int reportedWeekTime(int currentWeek, string username) 
     { 
      var totalTime = (from u in context.Users 
         from r in context.Reports 
         from w in context.Weeks 
         from d in context.Days 
         where u.Id == r.UserId && r.weekNr.Equals(currentWeek) && r.Id == w.ReportId && w.DayId == d.Id && u.Username.Contains(username) 
         select d.Hour).DefaultIfEmpty(0).Sum(); 
      return totalTime; 
     } 
+0

Może powinieneś ustawić nazwę użytkownika na właściwość w swojej klasie. Wiem, że WP7 Linq nie jest tak dobry z przekazanymi wartościami metody –

+0

musisz użyć join http://code.msdn.microsoft.com/LINQ-Join-Operators-dabef4e9 – Habib

+0

Przekazywanie nazwy użytkownika do metody takiej jak ta działa dla innego zapytania linq, którego używam, ale nie dla tego konkretnego. – rickard

Odpowiedz

2

Aktualizacja - podejście rozwiązywania problemów, należy utworzyć nową klasę anonimową z właściwością u.Username, nazwy użytkownika ciąg i porównania. Będzie łatwiej wyobrazić co się dzieje

var users = (from u in context.Users 
      select new 
      { 
       UsernameDb = u.Username, 
       UsernameSearch = username, 
       Comparison = u.Username.Contains(username), 
      }).ToList(); 

Original

chciałbym zmodyfikować zapytanie nieznacznie:

  1. Zastosowanie join 's zamiast from' sz where klauzul
  2. Usuń DefaultIfEmpty(0)

(1) jest bardziej dla czytelności, ale myślę, że (2) jest przyczyną problemu

var totalTime = (from u in context.Users 
       join r in context.Reports on u.Id equals r.UserId 
       join w in context.Weeks on r.Id equals w.ReportId 
       join d in context.Days on w.DayId equals d.Id 
       where r.weekNr.Equals(currentWeek) && u.Username.Contains(username) 
       select d.Hour).Sum(); 

Chciałbym również upewnić się, że poniższa kwerenda zwraca wynik. Jeśli nie, to to byłby twój problem.

var users = from u in context.Users 
      where u.Username.Contains(username) 
      select u; 
+0

Chciałbym wypróbować to, ale instrukcja select daje mi kod błędu "Operator" ?? nie może być zastosowany do operandów typu 'int' i 'int' " – rickard

+0

@rickard - Ok, założyłem, że d.Hour był zerowy. Czy próbowałeś usunąć DefaultIfEmpty (0)? Dlaczego to dodałeś? – Aducci

+0

Miałem DefaultIfEmpty, jeśli osoba dodała raporty, ale nie ma dodanych godzin. To by zwróciło wartość 0. Ale problem jest nadal tutaj, i wiem, że powinno to być retu Rn mnie wartość, ale nie ma. Zamiast tego daje mi "Odrzucenie do typu wartości" Int32 "nie powiodło się, ponieważ zmaterializowana wartość jest pusta - albo parametr ogólny typu wynikowego, albo zapytanie musi używać typu zerowego." – rickard