2013-07-30 2 views
1

Я застрял преобразование под sql в запрос LINQ. В основном, я просто хочу, чтобы сгруппировать мой экзамен в моей столового сорта, то вычислять для общего числа прошедшего, не удалось, количество раз, принятых и скорость прохожденияпреобразовать SQL-запрос в LINQ/dot нотацию

SELECT testID, 
(SELECT COUNT(testID) FROM tblGrade AS b 
    WHERE b.testID= a.testID AND b.Grade < 80) AS 'Failed', 
(SELECT COUNT(testID) FROM tblGrade AS b 
    WHERE b.testID= a.testIDAND b.Grade >= 80) AS 'Passed', 
--taken = failed + passed, 
--passingrate = (passed/taken) * 100 
FROM dbo.tblGrade AS a 
GROUP BY testID 
ORDER BY testID 

EDIT: Мое решение ниже: Это работает, но я думаю, что его не лучший способ, особенно неудавшееся и переданное имущество.

var xx1 = _unitOfWork.tblGrade.GetAll().GroupBy(a => new { a.testID}); 
var xx2 = xx1.Select(b => new 
      { 
      testID= b.Key.testID, 
      failed = _unitOfWork.tblGrade.Query(filter: a => a.testID == b.Key.testID).Where(c => c.Grade < 80).Count(), 
      passed = _unitOfWork.tblGrade.Query(filter: a => a.testID == b.Key.testID).Where(c => c.Grade >= 80).Count(), 
      //taken = failed + passed, 
      //passingrate = (passed/taken) * 100 
      }).ToList(); 
+0

спасибо. как я могу это использовать? – samantha07

ответ

1

Count() может принять предикат (Expression<Func<T, bool>>) в качестве аргумента, так что я думаю, что вы можете просто сделать

var xx2 = xx1.Select(b => new 
      { 
      testID= b.Key.testID, 
      failed = b.Count(x => x.Grade < 80), 
      passed = b.Count(x => x.Grade >=80), 
      taken = b.Count() 
      }) 
      .Select(b => new { 
       testID = b.TestID, 
       failed = b.failed, 
       passed = b.passed, 
       taken = b.taken, 
       passingrate = b.taken == 0 ? 0.0 : ((float)b.passed/b.taken) * 100 
      }).ToList(); 

Синтаксис запрос имеет (полезно в данном случае) let ключевое слово, так что может быть легче читать

var xx2 = from b in xx1 
      let failed = b.Count(x => x.Grade < 80) 
      let passed = b.Count(x => x.Grade >= 80) 
      let taken = failed + passed 
      select new { 
       testID = b.Key.TextID, 
       failed = failed, 
       passed = passed, 
       taken = taken, 
       passingrate = taken == 0 ? 0.0 : ((float)passed/taken) * 100 
      } 
+0

отличный ответ. но как насчет «WHERE b.testID = a.testID» в sql-запросе, это будет действовать с помощью «b.Count (x => x.Grade <80)» ??? – samantha07

+0

@ samantha07 хорошо группировка делается. Таким образом, вы уже сгруппированы по testID. Граф будет «по testID» –

+0

@ samantha07 Я бы не написал «базовый SQL-запрос», как вы это делали, кстати;) –

0

Это, как я хотел бы сделать это:

var h = list.GroupBy(a => a.testID) 
      .Select(a => { 
       int _failed = a.Count(g => g.Grade < 80); 
       int _passed = a.Count(g => g.Grade >= 80); 
       int _rate = (int)(_passed/(double)a.Count() * 100.0); 

       return new { 
       testID = a.Key, 
       failed = _failed, 
       passed = _passed, 
       taken = a.Count(), 
       rate = _rate, 
       };  
      }); 

Полный тестовый код:

void Main() 
{ 
    List<aGrade> list = new List<aGrade>() { 
    new aGrade() { Grade = 40, testID = 1 }, 
    new aGrade() { Grade = 50, testID = 1 }, 
    new aGrade() { Grade = 45, testID = 1 }, 
    new aGrade() { Grade = 70, testID = 1 }, 
    new aGrade() { Grade = 80, testID = 1 }, 
    new aGrade() { Grade = 90, testID = 1 }, 
    new aGrade() { Grade = 40, testID = 2 }, 
    new aGrade() { Grade = 50, testID = 2 }, 
    new aGrade() { Grade = 45, testID = 2 }, 
    new aGrade() { Grade = 70, testID = 2 }, 
    new aGrade() { Grade = 80, testID = 2 }, 
    new aGrade() { Grade = 90, testID = 2 }, 
    new aGrade() { Grade = 40, testID = 3 }, 
    new aGrade() { Grade = 50, testID = 3 }, 
    new aGrade() { Grade = 45, testID = 3 }, 
    new aGrade() { Grade = 70, testID = 3 }, 
    new aGrade() { Grade = 80, testID = 3 }, 
    new aGrade() { Grade = 90, testID = 3 }, 
    };  

    var h = list.GroupBy(a => a.testID) 
      .Select(a => { 
       int _failed = a.Count(g => g.Grade < 80); 
       int _passed = a.Count(g => g.Grade >= 80); 
       int _rate = (int)(_passed/(double)a.Count() * 100.0); 

       return new { 
       testID = a.Key, 
       failed = _failed, 
       passed = _passed, 
       taken = a.Count(), 
       rate = _rate, 
       };  
      }); 
    h.Dump(); 
} 
// Define other methods and classes here 

public class aGrade 
{ 
    public int Grade { get; set; } 
    public int testID { get; set; } 
} 

NB - Этот код будет работать как в LINQPad. (linqpad.com) Я рекомендую linqpad для тестирования этого типа кода ... делает вашу работу, ох так просто. Попробуй.

Смежные вопросы