Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Bom dia galera, estou desenvolvendo uma aplicação para uso próprio, utilizando windows form e entity framework 6, e estou com algumas dúvidas.
Tenho 2 tabelas:
DESPESA (ID_DESPESA, VALOR, ID_CATEGORIA)
CATEGORIA (ID_CATEGORIA, DESCRICAO)
1 - Estou utilizando somente a classe de mapeamento que o próprio entity criou para fazer para todo CRUD. Isso é correto ou eu deveria usar um Model meu próprio?
2 - Estou utilizando GridView para listar os registros, é o mais apropriado?
3 - No meu DAO uso o retorno List<TABELA> está correto?
4 - Estou tendo dificuldade de fazer o Join na consulta pra listar as Despesas e pegar a descrição da Categoria, não sei se estou fazendo certo.
DAO:
public List<DESPESA> getDespesas(int mes, int ano)
{
using (DB_MinhasFinancasEntities contexto = new DB_MinhasFinancasEntities())
{
var despesas = (from d in contexto.DESPESA
join c in contexto.CATEGORIA on d.ID_CATEGORIA equals c.ID_CATEGORIA
where d.DATA.Month == mes && d.DATA.Year == ano
select d).ToList<DESPESA>();
return despesas;
}
}
Form que lista as Despesas:
grdDespesas.DataSource = DespesaBO
.getDespesas(mes, ano)
.Select(d => new
{
ID = d.ID_DESPESA
, CATEGORIA = d.CATEGORIA.DESCRICAO
, VALOR = d.VALOR.ToString("N2")
}).ToList();
Classe de Mapeamento que o Entity criou:
namespace DB_EntityFramework
{
using System;
using System.Collections.Generic;
public partial class DESPESA
{
public int ID_DESPESA { get; set; }
public decimal VALOR { get; set; }
public int ID_CATEGORIA { get; set; }
public virtual CATEGORIA CATEGORIA { get; set; }
}
}
Fazendo assim a GridView fica totalmente vazia, sem mesmo os nomes das colunas, depois de algumas tentativas ele dá esse erro:
Additional information: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Ficaria muito agradecido se alguém pode-se tirar todas minhas dúvidas.
Abraço.
Muito obrigado Ivan, sua resposta me ajudou e me deixou mais tranquilo por saber que estou fazendo da forma certa.
Confirma uma coisa, no caso então você criou um classe para retornar todos os dados do JOIN, no caso se eu tivesse um terceiro Join, por exemplo com a Tabela de Usuario ficaria assim?
public class DESPESAS
{
public int ID_DESPESA { get; set; }
public decimal VALOR { get; set; }
public int ID_CATEGORIA { get; set; }
public string CATEGORIA { get; set; }
public int ID_USUARIO { get; set; }
public string USUARIO { get; set; }
}
Vou sempre ter que criar uma classe que envolva todos os Join's.
Você então usou o que eu perguntei na primeira pergunta.
Então. tem que criar uma nova classe, pois ao utilizar using(object), euquanto está em uso vc tem acesso aos objetos do join, ao sair do using o objeto é descartado.
Se você fizer um teste assim, verá que não acontecerá erro:
public List<DESPESA> getDespesas(int mes, int ano)
{
var contexto = new DB_MinhasFinancasEntities();
var despesas = (from d in contexto.DESPESA
join c in contexto.CATEGORIA on d.ID_CATEGORIA equals c.ID_CATEGORIA
where d.DATA.Month == mes && d.DATA.Year == ano
select d).ToList<DESPESA>();
return despesas;
}Ivan, eu testei como você fez e funcionou, porém eu tentei de uma outra forma e não está rolando, da uma olhada:
Despesa:
public class Despesa
{
private int idDespesa;
private decimal valor;
private Categoria categoria;
public int IdDespesa
{
get { return idDespesa; }
set { idDespesa = value; }
}
public decimal Valor
{
get { return valor; }
set { valor = value; }
}
internal Categoria Categoria
{
get { return categoria; }
set { categoria = value; }
}
}
Categoria
public class Categoria
{
private int idCategoria;
private String descricao;
public int IdCategoria
{
get { return idCategoria; }
set { idCategoria = value; }
}
public String Descricao
{
get { return descricao; }
set { descricao = value; }
}
}
DAO
using (DB_MinhasFinancasEntities contexto = new DB_MinhasFinancasEntities())
{
var despesas = contexto.DESPESA.Where(d => d.DATA.Month == mes && d.DATA.Year == ano)
.Select(d => new Despesa
{
IdDespesa = d.ID_DESPESA,
Valor = d.VALOR,
Categoria = d.CATEGORIA, // <<<< ERRO AQUI
};
return despesas;
}
Ele diz que Não é possível converter implicitamente o tipo 'DB_EntityFramework.CATEGORIA' em 'Projeto.Model.Categoria'
Não consigo acessar o IdCategoria e Descricao da categoria, a partir do atributo Categoria de Despesa.
Pode ser feito dessa forma ou somente como você fez?
Dessa forma que vc fez esta errado, pois a classe que vc criou é um objeto diferente da que vem do banco, ate daria certo se ficasses assim:
using (DB_MinhasFinancasEntities contexto = new DB_MinhasFinancasEntities())
{
var despesas = contexto.DESPESA.Where(d => d.DATA.Month == mes && d.DATA.Year == ano)
.Select(d => new Despesa};
return despesas;
}Funcionou certinho amigo, muito obrigado pela ajuda.
Abraço..
1 - Estou utilizando somente a classe de mapeamento que o próprio entity criou para fazer para todo CRUD. Isso é correto ou eu deveria usar um Model meu próprio?
È correto sim. Mas você pode criar a sua caso utilize programe em Code First
2 - Estou utilizando GridView para listar os registros, é o mais apropriado?
Em caso de listas sim
3 - No meu DAO uso o retorno List<TABELA> está correto?
Também está correto.
Depois da uma lida aqui http://www.linhadecodigo.com.br/artigo/780/generics-e-a-performance-no-net-framework-20.aspx para saber questões de performace
4 - Estou tendo dificuldade de fazer o Join na consulta pra listar as Despesas e pegar a descrição da Categoria, não sei se estou fazendo certo.
public class DESPESAS
{
public int ID_DESPESA { get; set; }
public decimal VALOR { get; set; }
public int ID_CATEGORIA { get; set; }
public string CATEGORIA { get; set; }
}
{
CATEGORIA = d.CATEGORIA.DESCRICAO,
VALOR = d.VALOR.ToString("N2")