Array
(
)

Ajuda com estudo de caso em .NET

Elber
   - 20 out 2014

Olá amigos. Sou um programador autodidata, e como consequência, estou tendo algumas dificuldades. Vejam se podem ajudar:
Fiz um sistema de pesquisa de opinião. A tabela de resultados (é uma View no SQL SERVER) ficou assim:
Clique na imagem para abrir em uma nova janela
Agora preciso tabular os resultados numa forma que gere gráficos. Então fiz uma query exatamente como precisava: coloquei o nome do professor, o grau de satisfação e os resultados em um COUNT por pergunta. Uma imagem que representa isso está aí:
Clique na imagem para abrir em uma nova janela
O código em SQL funciona muito bem. Aí eu criei o código em LINQ. no LINQPad funcionou perfeitamente. Estou colocando os dois códigos abaixo. Primeiro o SQL e depois o LINQ:
SQL:
#Código

SELECT 
	t1.prof_nome, 
	CASE t1.resu1
	 WHEN '60' THEN 'Regular'
	 WHEN '80' THEN 'Bom'
	 WHEN '90' THEN 'Ótimo'
	 WHEN '100' THEN 'Excelente'
	 End as resultado,
	t1.perguntas as p1, t2.perguntas as p2, t3.perguntas as p3, t4.perguntas as p4, 
	t5.perguntas as p5, t6.perguntas as p6, t7.perguntas as p7
FROM 
(select prof_nome, resu1, COUNT(resu1) as perguntas from view_ok
group by prof_nome, resu1) AS t1

left join

(select prof_nome, resu2, COUNT(resu2) as perguntas from view_ok 
group by prof_nome, resu2) AS t2

on

t1.prof_nome = t2.prof_nome
and t1.resu1 = t2.resu2

left join

(select prof_nome, resu3, COUNT(resu3) as perguntas from view_ok 
group by prof_nome, resu3) AS t3

on

t1.prof_nome = t3.prof_nome
and t1.resu1 = t3.resu3

left join

(select prof_nome, resu4, COUNT(resu4) as perguntas from view_ok 
group by prof_nome, resu4) AS t4

on

t1.prof_nome = t4.prof_nome
and t1.resu1 = t4.resu4

left join

(select prof_nome, resu5, COUNT(resu5) as perguntas from view_ok 
group by prof_nome, resu5) AS t5

on

t1.prof_nome = t5.prof_nome
and t1.resu1 = t5.resu5

left join

(select prof_nome, resu6, COUNT(resu6) as perguntas from view_ok
group by prof_nome, resu6) AS t6

on

t1.prof_nome = t6.prof_nome
and t1.resu1 = t6.resu6

left join

(select prof_nome, resu7, COUNT(resu7) as perguntas from view_ok 
group by prof_nome, resu7) AS t7

on

t1.prof_nome = t7.prof_nome
and t1.resu1 = t7.resu7

where t1.prof_nome = 'Elber Rizziolli Domingos'

CÓDIGO LINQ (Como possibilidade de parametrização):
#Código
string sexo = "1";
string r8 = "80";
string r9 = "90";
string r10 = "";
string r11 = "";

var query = 
from t0 in (
	(from v0 in View_ok
	group v0 by new {
		v0.Prof_nome,
		v0.Resu1
	} into g
	select new {
		g.Key.Prof_nome,
		g.Key.Resu1}))
join t1 in (
	from v1 in View_ok
		where Convert.ToString(v1.Resu8).Contains(r8) && Convert.ToString(v1.Resu9).Contains(r9) 
		&& Convert.ToString(v1.Resu10).Contains(r10) && Convert.ToString(v1.Resu11).Contains(r11) && Convert.ToString(v1.Sexo).Contains(sexo)
	group v1 by new {
	  v1.Prof_nome,
	  v1.Resu1
	} into g
	select new {
	  g.Key.Prof_nome,
	  g.Key.Resu1,
	  perguntas = g.Count(p => p.Resu1 != null)
	})
      on new { t0.Prof_nome, t0.Resu1 }
  equals new { t1.Prof_nome, Resu1 = t1.Resu1 } into t1_join
from t1 in t1_join.DefaultIfEmpty()
join t2 in (
	(from v2 in View_ok
		where Convert.ToString(v2.Resu8).Contains("") && Convert.ToString(v2.Resu9).Contains("")
		&& Convert.ToString(v2.Resu10).Contains("") && Convert.ToString(v2.Resu11).Contains("") && Convert.ToString(v2.Sexo).Contains("1")
	group v2 by new {
	  v2.Prof_nome,
	  v2.Resu2
	} into g
	select new {
	  g.Key.Prof_nome,
	  g.Key.Resu2,
	  perguntas = g.Count(p => p.Resu2 != null)
	}))
      on new { t0.Prof_nome, t0.Resu1 }
  equals new { t2.Prof_nome, Resu1 = t2.Resu2 } into t2_join
from t2 in t2_join.DefaultIfEmpty()
join t3 in (
	(from v3 in View_ok
		where Convert.ToString(v3.Resu8).Contains("") && Convert.ToString(v3.Resu11).Contains("")
		&& Convert.ToString(v3.Resu10).Contains("") && Convert.ToString(v3.Resu11).Contains("") && Convert.ToString(v3.Sexo).Contains("1")
	group v3 by new {
	  v3.Prof_nome,
	  v3.Resu3
	} into g
	select new {
	  g.Key.Prof_nome,
	  g.Key.Resu3,
	  perguntas = g.Count(p => p.Resu3 != null)
	}))
      on new { t0.Prof_nome, t0.Resu1 }
  equals new { t3.Prof_nome, Resu1 = t3.Resu3 } into t3_join
from t3 in t3_join.DefaultIfEmpty()
join t4 in (
	(from v4 in View_ok
		where Convert.ToString(v4.Resu8).Contains("60") && Convert.ToString(v4.Resu11).Contains("60")
		&& Convert.ToString(v4.Resu10).Contains("") && Convert.ToString(v4.Resu11).Contains("") && Convert.ToString(v4.Sexo).Contains("1")
	group v4 by new {
	  v4.Prof_nome,
	  v4.Resu4
	} into g
	select new {
	  g.Key.Prof_nome,
	  g.Key.Resu4,
	  perguntas = g.Count(p => p.Resu4 != null)
	}))
      on new { t0.Prof_nome, t0.Resu1 }
  equals new { t4.Prof_nome, Resu1 = t4.Resu4 } into t4_join
from t4 in t4_join.DefaultIfEmpty()
join t5 in (
	(from v5 in View_ok
		where Convert.ToString(v5.Resu8).Contains("") && Convert.ToString(v5.Resu11).Contains("")
		&& Convert.ToString(v5.Resu10).Contains("") && Convert.ToString(v5.Resu11).Contains("") && Convert.ToString(v5.Sexo).Contains("1")
	group v5 by new {
	  v5.Prof_nome,
	  v5.Resu5
	} into g
	select new {
	  g.Key.Prof_nome,
	  g.Key.Resu5,
	  perguntas = g.Count(p => p.Resu5 != null)
	}))
      on new { t0.Prof_nome, t0.Resu1 }
  equals new { t5.Prof_nome, Resu1 = t5.Resu5 } into t5_join
from t5 in t5_join.DefaultIfEmpty()
join t6 in (
	(from v6 in View_ok
		where Convert.ToString(v6.Resu8).Contains("") && Convert.ToString(v6.Resu11).Contains("")
		&& Convert.ToString(v6.Resu10).Contains("") && Convert.ToString(v6.Resu11).Contains("") && Convert.ToString(v6.Sexo).Contains("1")
	group v6 by new {
	  v6.Prof_nome,
	  v6.Resu6
	} into g
	select new {
	  g.Key.Prof_nome,
	  g.Key.Resu6,
	  perguntas = g.Count(p => p.Resu6 != null)
	}))
      on new { t0.Prof_nome, t0.Resu1 }
  equals new { t6.Prof_nome, Resu1 = t6.Resu6 } into t6_join
from t6 in t6_join.DefaultIfEmpty()
join t7 in (
	(from v7 in View_ok
		where Convert.ToString(v7.Resu8).Contains("") && Convert.ToString(v7.Resu11).Contains("")
		&& Convert.ToString(v7.Resu10).Contains("") && Convert.ToString(v7.Resu11).Contains("") && Convert.ToString(v7.Sexo).Contains("1")
	group v7 by new {
	  v7.Prof_nome,
	  v7.Resu7
	} into g
	select new {
	  g.Key.Prof_nome,
	  g.Key.Resu7,
	  perguntas = g.Count(p => p.Resu7 != null)
	}))
      on new { t0.Prof_nome, t0.Resu1 }
  equals new { t7.Prof_nome, Resu1 = t7.Resu7 } into t7_join
from t7 in t7_join.DefaultIfEmpty()
where
  t0.Prof_nome.Contains("Elber Rizziolli Domingos")
orderby t0.Resu1
select new {
  t0.Prof_nome,
  resultado = Convert.ToString(t0.Resu1) == "60" ? "Regular" : Convert.ToString(t0.Resu1) == "80" ? "Bom" : 
  Convert.ToString(t0.Resu1) == "90" ? "Ótimo" : Convert.ToString(t0.Resu1) == "100" ? "Excelente" : null,
  p1 = (int?)t1.perguntas,
  p2 = (int?)t2.perguntas,
  p3 = (int?)t3.perguntas,
  p4 = (int?)t4.perguntas,
  p5 = (int?)t5.perguntas,
  p6 = (int?)t6.perguntas,
  p7 = (int?)t7.perguntas
};

query.Dump();

MINHA DÚVIDA:
1 - Esta forma de trabalhar está boa?
2 - Não consegui gerar o código dentro do Visual Studio. Tentei criar uma nova classe, mas dá erro de inferência de tipo:
Cannot implicitly convert type System.Collections.Generic.List<AnonymousType#1> to System.Collections.Generic.IList<PesquisaView.view_ok>
Se eu acerto a inferência, dá que o sistema Entity Framework não suporta: 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll Additional information: The entity or complex type 'PesquisaBETAModel.view_ok' cannot be constructed in a LINQ to Entities query
Um exemplo de código bem resumido que tentei no Visual Studio:
#Código
public List<view_ok> ListarPesquisa(string prof)
    {
        PesquisaBETAEntities pb = new PesquisaBETAEntities();

        var query = (from t0 in
                         (from v0 in pb.view_ok
                          group v0 by new
                          {
                              v0.prof_nome,
                              v0.resu1
                          }
                              into gg
                              select new
                              {
                                  gg.Key.prof_nome,
                                  gg.Key.resu1
                              })
                       where t0.prof_nome.Contains(prof)
                     select new view_ok{ Professor = t0.prof_nome, P1 = t0.resu1 }).ToList();

        return query;

    }

Se algum puder me ajudar? Preciso criar um método em LINQ que gere o resultado exemplificado em SQL acima. Já tentei achar de tudo, mas não achei com uma complexidade grande como tenho no meu LINQ, apenas coisas mais simples.
Obrigado.

Pjava
   - 20 out 2014

Em outro post seu, falamos do Convert.ToString(). Dissemos lá que essa conversão, dentro da linq não funciona. Você deve ter o código mais natural possível dentro da linq e depois fora do escopo da linq, usar a cláusula Where e ir atribuindo seus filtros na pesquisa, se possível mesclando com lambda expression, como eu te passei como exemplo em outro post seu. Com expressões complexas, e melhor trabalhar assim com LINQ, os filtros fora. Dá para fazer dentro também, mas a maioria usa assim. Achei a segunda LINQ melhor, aí sim, você faria os filtros fora do escopo, tipo:

query = query.Where(x => x.meu_campo == qualquer_coisa_aqui) e assim por diante.