ORIENTACAO A OBJETOS - CONCEITO
Field field = (Field)item.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(Field));
field= (Field)item.GetCustomAttributes(true)[0];
A diferença dessas duas linhas:
A primeira, busca o primeiro CustomAttribute que encontrar na propriedade representada por [Ô]item[Ô], em que o tipo seja [Ô]Field[Ô]
A segunda, busca o primeiro CustomeAttribute de field.
Acho que no framework 2.0, você deve antes explicitamente converter a array de CustomAttributes para List:
field = field= (Field)item.GetCustomAttributes(true).ToList().FirstOrDefault(x => x.GetType() == typeof(Field));
Se é que eu entendi sua pergunta
field= (Field)item.GetCustomAttributes(true)[0];
A diferença dessas duas linhas:
A primeira, busca o primeiro CustomAttribute que encontrar na propriedade representada por [Ô]item[Ô], em que o tipo seja [Ô]Field[Ô]
A segunda, busca o primeiro CustomeAttribute de field.
Acho que no framework 2.0, você deve antes explicitamente converter a array de CustomAttributes para List:
field = field= (Field)item.GetCustomAttributes(true).ToList().FirstOrDefault(x => x.GetType() == typeof(Field));
Se é que eu entendi sua pergunta
Kerplunk, você entendeu perfeitamente a minha pergunta. Estive olhando aqui mas o framework 2.0 não tem o método ToList() e nem como usar as expressões lambda.
Existe uma maneira mais prática de pegar esse primeiro atributo sem ter de usar um foreach?
Existe uma maneira mais prática de pegar esse primeiro atributo sem ter de usar um foreach?
Já ia me esquecendo. Segue a minha classe singleton para database.
Modo de usar:
Sugestões e crÃticas serão bem-vindas.
using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace DBFactory
{
public sealed class Database
{
// propriedade para singleton da classe
private static readonly Database instance = new Database();
// variaveis para conexão singleton
string _connString;
// cria a instância da classe
private Database() { }
// retorna a instância singleton
public static Database GetInstance { get { return instance; } }
// string de conexão
public string ConnectionCommand { get { return _connString; } set { _connString = value; } }
// retornar uma nova conexão; útil para se trabalhar com vários datareaders ao mesmo tempo
public static SqlConnection GetNewConnection()
{
try
{
SqlConnection newConn = new SqlConnection(instance.ConnectionCommand);
newConn.Open();
return newConn;
}
catch
{
return null;
}
}
// retorna a data e hora do servidor (MSSQL Server)
public static DateTime GetDateTime()
{
DateTime dhServ = DateTime.Now;
try
{
// Abre uma nova conexão
SqlConnection connGetDateTime = new SqlConnection(instance.ConnectionCommand);
connGetDateTime.Open();
// Recupera a data e hora atual do servidor SQL Server
string sql = [Ô]SELECT GETDATE() AS hora_atual;[Ô];
SqlCommand cmd = new SqlCommand(sql);
cmd.Connection = connGetDateTime;
cmd.Prepare();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) { dhServ = Convert.ToDateTime(dr[[Ô]hora_atual[Ô]]); }
dr.Dispose();
dr.Close();
connGetDateTime.Close();
connGetDateTime = null;
// Retorna a data e hora atual do servidor
return dhServ;
}
catch
{
return DateTime.Now;
}
}
}
}
Modo de usar:
// comando de consulta para cliente
sql = [Ô]SELECT * FROM clientes WHERE (id = @id);[Ô];
cmd = new SqlCommand(sql, Database.GetNewConnection());
cmd.Parameters.Add([Ô]@id[Ô], SqlDbType.Int, 4).Value = idCliente;
dr = cmd.ExecuteReader();
Sugestões e crÃticas serão bem-vindas.
FFCOUTO,
Seria algo do tipo:
Seria algo do tipo:
PropertyInfo[] arr = item.GetCustomAttributes(true);
List<PropertyInfo> listPara = new List<PropertyInfo>(arr);
field= (Field)listPara.FirstOrDefault(x => x.GetType() == typeof(Field));
Kerplunk, desculpe se estou sendo chato, mas o método FirstOrDefault não existe na versão 2.0 do framework. E também não é possÃvel criar métodos de extensão para esta versão.
Eu estou tentando usar delegates mas estou com alguma dificuldade pois sempre mostra os dois erros abaixo:
Desde já deixo meus agradecimentos pela ajuda.
Eu estou tentando usar delegates mas estou com alguma dificuldade pois sempre mostra os dois erros abaixo:
Citação:The best overloaded method match for [ô]System.Collections.Generic.List<object>.Find(System.Predicate<object>)[ô] has some invalid arguments
Argument [ô]1[ô]: cannot convert from [ô]anonymous method[ô] to [ô]System.Predicate<object>[ô]
Desde já deixo meus agradecimentos pela ajuda.
FFCOUTO,
Para o Framework 2.0, use:
O erro que você está tendo é porque no framework 2.0, reflection ainda não estava tão maduro quanto está hoje.
Para o Framework 2.0, use:
Field field = (Field)item.GetCustomAttributes(typeof(Field), true)[0];
O erro que você está tendo é porque no framework 2.0, reflection ainda não estava tão maduro quanto está hoje.
Só uma dica, se você está usando o VS.Net 2010 ou superior (talvez com o 2008 também funcione), mesmo que você use o Framework 2.0 você ainda pode usar Linq to Objects e expressões Lambda.
O compilador usado pelo VS.Net suporta estes recursos, só que o framework 2.0 não possui as classes necessárias, então o que precisa ser feito é usar uma biblioteca que adicione as classes necessárias, neste caso existe o LINQBridge que pode ser instalado no projeto direto pelo NuGet.
Com isso você vai poder usar por exemplo o FirstOrDefault e o ToList sem problemas no .Net 2.0
O compilador usado pelo VS.Net suporta estes recursos, só que o framework 2.0 não possui as classes necessárias, então o que precisa ser feito é usar uma biblioteca que adicione as classes necessárias, neste caso existe o LINQBridge que pode ser instalado no projeto direto pelo NuGet.
Com isso você vai poder usar por exemplo o FirstOrDefault e o ToList sem problemas no .Net 2.0
Citação::
FOXMAN,
Você pode usar uma decoração de propriedade, que nada mais é que uma classe que herde da classe Attribute:
public class Campo : Attribute
{
public bool Obrigatorio {get;set;}
}
Então na sua classe faça:
public class Carro
{
[Campo(Obrigatorio=true)]
public int x {get; set;}
[Campo(Obrigatorio=false)]
public int y {get;set;}
}
Ao percorrer as propriedades, use o método GetCustomAttribute para buscar o atributo obrigatório:
Carro car = new Carro();
foreach (PropertyInfo item in car.GetType().GetProperties())
{
Campo cmp = (Campo)item.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(Campo));
if (cmp.Obrigatorio == true)
Console.WriteLine(string.Format([Ô]Propriedade {0} é VERDADEIRA[Ô], item.Name, cmp.Obrigatorio));
else
Console.WriteLine(string.Format([Ô]Propriedade {0} é FALSA[Ô], item.Name, cmp.Obrigatorio));
}
Console.ReadKey();
Veja que o detalhe importante no exemplo. Dentro do foreach, eu pego o atributo do tipo Campo da propriedade, utilizando um simples FirstOrDefault. Esse é o grande barato da coisa, propriedades, podem ter mais de um atributo, na verdade, podem ter vários, um para cada finalidade. Se tiver alguma dúvida, estamos ae
Kerplunk, maravilha isto já resolveu meu problema.
O engraçado é que eu havia até feito algo parecido, mas declarei um método ao invés de uma propriedade. E sem dúvida seu esclarecimento foi absolutamente exclarecedor.....
Obrigado.
Citação:Para o Framework 2.0, use:
Field field = (Field)item.GetCustomAttributes(typeof(Field), true)[0];
Kerplunk, funcionou perfeitamente.
Só uma esclarecimento quanto ao método ConvertDrToEntity postado como exemplo. Ao fazer a carga de uma tabela completa o processamento é demasiado lento, visto que são várias conversões utilizados, portanto, recomendo o uso para leitura de poucos registros. Na tabela que usei como teste, ela tinha apenas 2500 registros e demorou pouco mais 5 minutos para o carregamento completo.
é possÃvel otimizar o uso dessa rotina?
Abraços,
FFCOUTO,
O framework 2.0, não é muito otimizado para uso de reflection. À partir do 3.5 essas funcionalidades foram muito otimizadas melhorando em muito o desempenho.
O framework 2.0, não é muito otimizado para uso de reflection. À partir do 3.5 essas funcionalidades foram muito otimizadas melhorando em muito o desempenho.
Faça seu login para responder