Persistência de dados com Reflection - C#

Veja neste artigo como criar uma camada de persistência de dados com reflection.

Nesse artigo vou mostrar como criar a camada de persistência de dados com reflection.

O uso de reflection pode diminuir a performance do sistema, para atribuir um valor em uma propriedade da classe, primeiro o algoritmo vai procurar a propriedade da classe e depois vai atribuir o valor, sendo que o uso normal não tem esse tempo de procura.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace Reflection { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Cliente oCliente =new Cliente(); oCliente.Name ="Cliente 1"; oCliente.SetValue("Name","Cliente 1"); Console.Read(); } } public class Cliente { private string _name; public string Name { get { return _name; } set {_name = value;} } public void SetValue(stringnameProperty, object value) { PropertyInfo[]arrayPropertyInfo = this.GetType().GetProperties(); for (int index = 0; index <arrayPropertyInfo.Length; index++) { if(arrayPropertyInfo[index].Name == nameProperty) { arrayPropertyInfo[index].SetValue(this,value, null); } } } } }
Deve ser analisado o que é será importante no desenvolvimento, a perfomance do sistema ou o ganho de tempo no desenvolvimento,utilizo quando preciso criar pequenos projetos ou quando o prazo de entrega é curto.

Separei as classes em pacotes.

EN – Classes de Entidade
DAO – Classes de acesso de dados.
Data – Classes que contém os métodos para inserir, consultar, atualizar e excluir dados no banco de dados.

As classes desses pacotes são acessíveis somente na dll que foram criadas. Para acessar os métodos criei uma classe facade chamada FacadeDAO, essa classe é utilizada para expor os métodos das classes DAO, para acessar as propriedades das classes EN, foram criadas interfaces.


Abaixo  mostro em diagramas como ficou a estrutura.



 




No pacote Data foi criado uma classe abstrata e duas classes que herdam dela, a classe DatabasePostgresql disponibiliza métodos para acessar o banco de dados PostgreSql e a classe DatabaseSqlServer disponibiliza métodos para acessar o banco de dados Sql Server.
A classe Database foram criados métodos abstratos, obrigando as classes que herdam implementar os métodos. Isso disponibiliza ao sistema acessar 2 bancos diferentes.

Classe Database.

using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; namespace Persistencia.Data.Base { abstract class Database { private int _commandTimeOut; public int CommandTimeOut { get { return _commandTimeOut; } set {_commandTimeOut = value;} } publicDatabase(int commandTimeOut) { this.CommandTimeOut =commandTimeOut; } public abstract ConnectionStateStateConnection { get; } public abstract voidConnectionOpen(string stringConnection); public abstract voidConnectionClose(); public abstract voidBeginTransacTion(); public abstract voidComitTransacTion(); public abstract voidRollBack(); public abstract DataSetExecuteDataAdapter_DataSet(string strSql); public abstract DataTableExecuteDataAdapter_DataTable(string strSql); public abstract DataRowExecuteDataRow(string strSql); public abstract voidExecuteDataReader(string strSql, Action<IDataReader>action); public abstract objectExecuteScalar(string strSql); public abstract objectExecuteScalar(string strSql, List<IDbDataParameter>parameterCollection); public abstract voidExecuteNonQuery(string strSql, List<IDbDataParameter>parameterCollection); public abstract voidExecuteNonQuery(string strSql); public abstract IDbDataParameterCreateObjectParameter(bool isNullable); public abstract stringCommandLastIdentity(); } }

Classe DatabasePostgreSql. Para usar essa classe é preciso adicionar a dll Npgsql.dll na referência no projeto.

using System; using System.Collections.Generic; using System.Text; using System.Data; using Npgsql; using Persistencia.Data.Base; namespace Persistencia.Data { class DatabasePostgreSQL : Database { public override ConnectionStateStateConnection { get { if(oNpgsqlConnection != null) { returnoNpgsqlConnection.State; } else { returnConnectionState.Closed;} } } private NpgsqlConnection oNpgsqlConnection; private NpgsqlTransaction oNpgsqlTransaction; publicDatabasePostgreSQL(int commandTimeOut) : base(commandTimeOut) { } public override voidConnectionOpen(string stringConnection) { oNpgsqlConnection = new NpgsqlConnection(stringConnection); oNpgsqlConnection.Open(); } public override voidConnectionClose() { if(oNpgsqlTransaction != null) { oNpgsqlTransaction.Dispose(); oNpgsqlTransaction = null; } if(oNpgsqlConnection != null) { if(oNpgsqlConnection.State == ConnectionState.Open) { oNpgsqlConnection.Close(); } oNpgsqlConnection.Dispose(); oNpgsqlConnection = null; } } public override voidBeginTransacTion() { oNpgsqlTransaction = oNpgsqlConnection.BeginTransaction(); } public override voidComitTransacTion() { oNpgsqlTransaction.Commit(); } public override voidRollBack() { oNpgsqlTransaction.Rollback(); } public override DataSetExecuteDataAdapter_DataSet(string strSql) { DataSetoDataSet = newDataSet(); NpgsqlCommandoNpgsqlCommand = newNpgsqlCommand(); oNpgsqlCommand.CommandText= strSql; oNpgsqlCommand.CommandTimeout= CommandTimeOut; oNpgsqlCommand.Connection= oNpgsqlConnection; oNpgsqlCommand.Transaction= oNpgsqlTransaction; NpgsqlDataAdapteroNpgsqlDataAdapter = new NpgsqlDataAdapter(oNpgsqlCommand); oNpgsqlDataAdapter.Fill(oDataSet); returnoDataSet; } public override DataTableExecuteDataAdapter_DataTable(string strSql) { DataTableoDataTable = newDataTable(); NpgsqlCommandoNpgsqlCommand = newNpgsqlCommand(); oNpgsqlCommand.CommandText= strSql; oNpgsqlCommand.CommandTimeout= CommandTimeOut; oNpgsqlCommand.Connection= oNpgsqlConnection; oNpgsqlCommand.Transaction= oNpgsqlTransaction; NpgsqlDataAdapteroNpgsqlDataAdapter = new NpgsqlDataAdapter(oNpgsqlCommand); oNpgsqlDataAdapter.Fill(oDataTable); returnoDataTable; } public override DataRowExecuteDataRow(string strSql) { DataRowoDataRow = null; DataTableoDataTable = newDataTable(); NpgsqlCommandoNpgsqlCommand = newNpgsqlCommand(); oNpgsqlCommand.CommandText= strSql; oNpgsqlCommand.CommandTimeout= CommandTimeOut; oNpgsqlCommand.Connection= oNpgsqlConnection; oNpgsqlCommand.Transaction= oNpgsqlTransaction; NpgsqlDataAdapteroNpgsqlDataAdapter = new NpgsqlDataAdapter(oNpgsqlCommand); oNpgsqlDataAdapter.Fill(oDataTable); if(oDataTable.Rows.Count> 0) { oDataRow =oDataTable.Rows[0]; } returnoDataRow; } public override voidExecuteDataReader(string strSql, Action<IDataReader>action) { NpgsqlCommandoNpgsqlCommand = newNpgsqlCommand(); oNpgsqlCommand.CommandText= strSql; oNpgsqlCommand.CommandTimeout= CommandTimeOut; oNpgsqlCommand.Connection= oNpgsqlConnection; oNpgsqlCommand.Transaction= oNpgsqlTransaction; NpgsqlDataReaderoNpgsqlDataReader = oNpgsqlCommand.ExecuteReader(); while(oNpgsqlDataReader.Read()) { action(oNpgsqlDataReader); } } public override objectExecuteScalar(string strSql) { NpgsqlCommandoNpgsqlCommand = newNpgsqlCommand(); oNpgsqlCommand.CommandText= strSql; oNpgsqlCommand.CommandTimeout= CommandTimeOut; oNpgsqlCommand.Connection= oNpgsqlConnection; oNpgsqlCommand.Transaction= oNpgsqlTransaction; returnoNpgsqlCommand.ExecuteScalar(); } public override objectExecuteScalar(string strSql, List<IDbDataParameter>parameterCollection) { NpgsqlCommandoNpgsqlCommand = newNpgsqlCommand(); oNpgsqlCommand.CommandText= strSql; oNpgsqlCommand.CommandTimeout= CommandTimeOut; oNpgsqlCommand.Connection= oNpgsqlConnection; oNpgsqlCommand.Transaction= oNpgsqlTransaction; parameterCollection.ForEach(delegate(IDbDataParameter item){ oNpgsqlCommand.Parameters.Add(item); }); returnoNpgsqlCommand.ExecuteScalar(); } public override voidExecuteNonQuery(string strSql, List<IDbDataParameter>parameterCollection) { NpgsqlCommandoNpgsqlCommand = newNpgsqlCommand(); oNpgsqlCommand.CommandText= strSql; oNpgsqlCommand.CommandTimeout= CommandTimeOut; oNpgsqlCommand.Connection= oNpgsqlConnection; oNpgsqlCommand.Transaction= oNpgsqlTransaction; parameterCollection.ForEach(delegate(IDbDataParameter item){ oNpgsqlCommand.Parameters.Add(item); }); oNpgsqlCommand.ExecuteNonQuery(); } public override voidExecuteNonQuery(string strSql) { NpgsqlCommandoNpgsqlCommand = newNpgsqlCommand(); oNpgsqlCommand.CommandText= strSql; oNpgsqlCommand.CommandTimeout= CommandTimeOut; oNpgsqlCommand.Connection= oNpgsqlConnection; oNpgsqlCommand.Transaction= oNpgsqlTransaction; oNpgsqlCommand.ExecuteNonQuery(); } public override IDbDataParameterCreateObjectParameter(bool isNullable) { NpgsqlParameteroNpgsqlParameter = newNpgsqlParameter(); oNpgsqlParameter.IsNullable= isNullable; return oNpgsqlParameter; } public override stringCommandLastIdentity() { return "SELECT lastval() AS Id;"; } } }

Classe DatabaseSqlServer.

using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using Persistencia.Data.Base; namespace Persistencia.Data { sealed class DatabaseSqlServer: Database { public override ConnectionStateStateConnection { get { if(oSqlConnection != null) { returnoSqlConnection.State; } else { returnConnectionState.Closed;} } } private SqlConnection oSqlConnection; private SqlTransaction oSqlTransaction; publicDatabaseSqlServer(int commandTimeOut) : base(commandTimeOut) { } public override voidConnectionOpen(string stringConnection) { oSqlConnection =new SqlConnection(stringConnection); oSqlConnection.Open(); } public override voidConnectionClose() { if(oSqlTransaction != null) { oSqlTransaction.Dispose(); oSqlTransaction = null; } if(oSqlConnection != null) { if(oSqlConnection.State == ConnectionState.Open) { oSqlConnection.Close(); } oSqlConnection.Dispose(); oSqlConnection = null; } } public override voidBeginTransacTion() { oSqlTransaction =oSqlConnection.BeginTransaction(); } public override voidComitTransacTion() { oSqlTransaction.Commit(); } public override voidRollBack() { oSqlTransaction.Rollback(); } public override DataSetExecuteDataAdapter_DataSet(string strSql) { DataSetoDataSet = newDataSet(); SqlCommandoSqlCommand = newSqlCommand(); oSqlCommand.CommandText= strSql; oSqlCommand.CommandTimeout= CommandTimeOut; oSqlCommand.Connection= oSqlConnection; oSqlCommand.Transaction= oSqlTransaction; SqlDataAdapteroSqlDataAdapter = newSqlDataAdapter(oSqlCommand); oSqlDataAdapter.Fill(oDataSet); returnoDataSet; } public override DataTableExecuteDataAdapter_DataTable(string strSql) { DataTableoDataTable = newDataTable(); SqlCommandoSqlCommand = newSqlCommand(); oSqlCommand.CommandText= strSql; oSqlCommand.CommandTimeout= CommandTimeOut; oSqlCommand.Connection= oSqlConnection; oSqlCommand.Transaction= oSqlTransaction; SqlDataAdapteroSqlDataAdapter = newSqlDataAdapter(oSqlCommand); oSqlDataAdapter.Fill(oDataTable); returnoDataTable; } public override DataRowExecuteDataRow(string strSql) { DataRowoDataRow = null; DataTableoDataTable = newDataTable(); SqlCommandoSqlCommand = newSqlCommand(); oSqlCommand.CommandText= strSql; oSqlCommand.CommandTimeout= CommandTimeOut; oSqlCommand.Connection= oSqlConnection; oSqlCommand.Transaction= oSqlTransaction; SqlDataAdapteroSqlDataAdapter = newSqlDataAdapter(oSqlCommand); oSqlDataAdapter.Fill(oDataTable); if(oDataTable.Rows.Count> 0) { oDataRow =oDataTable.Rows[0]; } returnoDataRow; } public override voidExecuteDataReader(string strSql, Action<IDataReader>action) { SqlCommandoSqlCommand = newSqlCommand(); oSqlCommand.CommandText= strSql; oSqlCommand.CommandTimeout= CommandTimeOut; oSqlCommand.Connection= oSqlConnection; oSqlCommand.Transaction= oSqlTransaction; SqlDataReaderoSqlDataReader = oSqlCommand.ExecuteReader(); while(oSqlDataReader.Read()) { action(oSqlDataReader); } } public override objectExecuteScalar(string strSql) { SqlCommandoSqlCommand = newSqlCommand(); oSqlCommand.CommandText= strSql; oSqlCommand.CommandTimeout= CommandTimeOut; oSqlCommand.Connection= oSqlConnection; oSqlCommand.Transaction= oSqlTransaction; returnoSqlCommand.ExecuteScalar(); } public override object ExecuteScalar(string strSql, List<IDbDataParameter> parameterCollection) { SqlCommandoSqlCommand = newSqlCommand(); oSqlCommand.CommandText= strSql; oSqlCommand.CommandTimeout= CommandTimeOut; oSqlCommand.Connection= oSqlConnection; oSqlCommand.Transaction= oSqlTransaction; parameterCollection.ForEach(delegate(IDbDataParameter item){ oSqlCommand.Parameters.Add(item); }); returnoSqlCommand.ExecuteScalar(); } public override voidExecuteNonQuery(string strSql, List<IDbDataParameter>parameterCollection) { SqlCommandoSqlCommand = newSqlCommand(); oSqlCommand.CommandText= strSql; oSqlCommand.CommandTimeout= CommandTimeOut; oSqlCommand.Connection= oSqlConnection; oSqlCommand.Transaction= oSqlTransaction; parameterCollection.ForEach(delegate(IDbDataParameter item){ oSqlCommand.Parameters.Add(item); }); oSqlCommand.ExecuteNonQuery(); } public override voidExecuteNonQuery(string strSql) { SqlCommandoSqlCommand = newSqlCommand(); oSqlCommand.CommandText= strSql; oSqlCommand.CommandTimeout= CommandTimeOut; oSqlCommand.Connection= oSqlConnection; oSqlCommand.Transaction= oSqlTransaction; oSqlCommand.ExecuteNonQuery(); } public override IDbDataParameterCreateObjectParameter(bool isNullable) { SqlParameteroSqlParameter = newSqlParameter(); oSqlParameter.IsNullable= isNullable; return oSqlParameter; } public override stringCommandLastIdentity() { return "SELECT SCOPE_IDENTITY() AS Id;"; } } }

No pacote EN foram criadas as classes e enumeradores:

StatusObject<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'="">  = enumerador para indicar o status da classe.
FieldAttribute = classe para configurar as propriedades das classes entidades.
TypeProperty = enumerador para indicar se a propriedade é um tipo,referência ou uma coleção.
BaseEN = classe que atribuí e retorna valores nas propriedades, cria os comandos INSERT, DELETE, UPDATE E SELECT para serem usados nas classesDAO.</spanstyle='font-size:12.0pt;font-family:"times>

public enum TypeProperty { Type = 0,//Indica que a propriedade é um tipo. Collection = 1,//Indica que a propriedade é uma coleção. Reference = 2,//Indica que a propriedade é uma referência. }

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Persistencia.EN { public enum TypeProperty { Type = 0,//Indica que a propriedade é um tipo. Collection = 1,//Indica que a propriedade é uma coleção. Reference = 2,//Indica que a propriedade é uma referência. } public enum StatusObject { New = 0,//Indica que a classe foi criada. Loaded = 1,//Indica que os dados foram carregados do banco de dados. Changed = 2,//Indica que a classe foi alterada. DeletedLoaded = 3,//Indica que o objeto pode ser excluído do banco de dados,informa que esse objeto foi carregado. DeletedChanged = 3,//Indica que o objeto pode ser excluído do banco de dados,informa que esse objeto foi alterado. } }

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.SqlClient; namespace Persistencia.EN.Base { public sealed class FieldAttribute : Attribute { private bool_isPrimaryKey;//Indica que o campo no banco de dados éuma chave primária. private bool_isForeignKey;//Indica que o campo no banco de dados éuma chave estrangeira. private TypeProperty _typeProperty;//Indica que tipo é a propriedade na classe. private string_nameField;//Nome do campo no banco de dados. private string_nameParam;//Nome do parâmetro utilizado nos métodosna classe DAO. private int_length;//Tamanho do campo no banco de dados. private DbType_dbType;//Tipo do campo no banco de dados. private bool_isNull;//Indica se o campo pode ser nulo no banco dedados. private byte_precision;//Precição do campo. private byte_scale;//Escala do campo. private object_value;//Propriedade utilizado para passar o valor dapropriedade. public bool IsPrimaryKey { get { return _isPrimaryKey; } private set { _isPrimaryKey =value; } } public bool IsForeignKey { get { return _isForeignKey; } private set { _isForeignKey =value; } } publicTypeProperty TypeProperty { get { return _typeProperty; } private set { _typeProperty =value; } } public string NameField { get { return _nameField; } private set { _nameField =value; } } public string NameParam { get { return _nameParam; } private set { _nameParam =value; } } public int Length { get { return _length; } private set { _length = value; } } public DbType DbType { get { return _dbType; } private set { _dbType = value; } } public bool IsNull { get { return _isNull; } private set { _isNull = value; } } public byte Precision { get { return _precision; } private set { _precision =value; } } public byte Scale { get { return _scale; } private set { _scale = value; } } public objectValue { get { return _value; } set {_value = value;} } publicFieldAttribute(bool isPrimaryKey, bool isForeignKey, TypeProperty typeProperty, string nameField, stringnameParam, int length, DbTypedbType, bool isNull) { this.IsPrimaryKey =isPrimaryKey; this.IsForeignKey =isForeignKey; this.TypeProperty =typeProperty; this.NameField =nameField; this.NameParam =nameParam; this.Length =length; this.DbType =dbType; this.IsNull =isNull; } publicFieldAttribute(bool isPrimaryKey, bool isForeignKey, TypeProperty typeProperty, string nameField, stringnameParam, int length, DbTypedbType, bool isNull, byteprecision, byte scale) { this.IsPrimaryKey =isPrimaryKey; this.IsForeignKey =isForeignKey; this.TypeProperty =typeProperty; this.NameField =nameField; this.NameParam =nameParam; this.Length =length; this.DbType =dbType; this.IsNull =isNull; this.Precision =precision; this.Scale =scale; } } }

Aclasse BaseEN é onde realmente utilizamos reflection.Vamos usar aclasses:

PropertyInfo<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'=""> = Classe com as informações das propriedades da classe. O método this.GetType().GetProperties()vai retornar uma coleção dessa classe, com o método PropertyInfo.GetCustomAttributes(true)vai retornar as classes de atributo, nesse caso vamos utilizar uma classe,que é FieldAttribute que herda da classe Attribute.</spanstyle='font-size:12.0pt;font-family:"times>

Precisamos de ssa classe para coletar as informações do campo no banco de dados, comotamanho, tipo, etc.

Assembly<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'=""> = Classe que vamos utilizar para criar instâncias das classes entidades, quando uma propriedade for uma referência, utilizaremos o método oAssembly<spanstyle='color:#400080'>.CreateInstance.</spanstyle='color:#400080'></spanstyle='font-size:12.0pt;font-family:"times>

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Reflection; namespace Persistencia.EN.Base { public abstract class BaseEN { private StatusObjectstatus;//Variável para guardar o status do objeto. private stringnameSchema;//Nome do schema que a tabela pertence nobanco de dados. private stringnameTable;//Nome da tabela no banco de dados. private stringnameIdParent;//Utilizado quando a classe tem umaclasse pai, no construtor a classe entidade passa para a classe base o nome // da propriedade. private FacadeDAO_oFacadeDAO;//Essa variável vai ser utilizada nasclasses Entidade. private Int64_id;//Todas as classes entidade vai ter umapropriedade Id. protected FacadeDAOoFacadeDAO { get { return _oFacadeDAO; } } [FieldAttribute(true,false, TypeProperty.Type, "bgId","@bgId", 0,System.Data.DbType.Int64, false)]//Configura apropriedade para o banco de dados. public Int64 Id { get { return _id; } set { _id = value; } } /// <summary> /// Construtor paraclasse de entidade que não é uma classe filho. /// </summary> /// <param name="nameSchema">Nome do schema que a tabela pertence no banco de dados.</param> /// <param name="nameTable">Nome da tabela no banco de dados.</param> /// <param name="oFacadeDAO">Objeto da classe FacadeDAO.</param> public BaseEN(string nameSchema, string nameTable, FacadeDAOoFacadeDAO) { this.status = StatusObject.New; this.nameSchema =nameSchema; this.nameTable =nameTable; this._oFacadeDAO =oFacadeDAO; } /// <summary> /// Construtor paraclasse de entidade que é uma classe filho. /// </summary> /// <param name="nameSchema">Nome do schema que a tabela pertence no banco de dados.</param> /// <param name="nameTable">Nome da tabela no banco de dados.</param> /// <param name="nameIdParent">Nome da propriedade que é pai da classe.</param> /// <param name="oFacadeDAO">Objeto da classe FacadeDAO.</param> public BaseEN(string nameSchema, string nameTable, stringnameIdParent, FacadeDAO oFacadeDAO) { this.status = StatusObject.New; this.nameSchema =nameSchema; this.nameTable =nameTable; this.nameIdParent =nameIdParent; this._oFacadeDAO =oFacadeDAO; } /// <summary> /// Obtém o status da classe. /// </summary> public StatusObject GetStatus() { return this.status; } /// <summary> /// Indica para aclasse DAO que essé objeto vai ser excluído do banco de dados. /// </summary> public void Remove() { if (this.status == StatusObject.Loaded) { this.status = StatusObject.DeletedLoaded; } else if (this.status == StatusObject.Changed) { this.status = StatusObject.DeletedChanged; } } /// <summary> /// Cancela a exclusão do banco de dados. /// </summary> public void UnRemove() { if (this.status == StatusObject.DeletedLoaded) { this.status = StatusObject.Loaded; } else if (this.status == StatusObject.DeletedChanged) { this.status = StatusObject.Changed; } } /// <summary> /// Altera o status da classe. /// </summary> internal void SetStatus(StatusObjectstatusObject) { this.status = statusObject; } /// <summary> /// Cria uma novainstância do classe. /// </summary> internal BaseEN NewInstance() { AssemblyoAssembly = this.GetType().Assembly; //Cria uma nova instância, passando comoparâmetro o objeto da classe FacadeDAO. return (BaseEN)oAssembly.CreateInstance(this.GetType().FullName,false, BindingFlags.CreateInstance, null,new object[] { this._oFacadeDAO}, null, null); } /// <summary> /// Constrói eretorna o comando SELECT. /// </summary> internal string GetSelect() { returngetSelect(null, null,null); } /// <summary> /// Constrói eretorna o comando SELECT. /// </summary> internal string GetSelect(longid) { returngetSelect(id, null, null); } /// <summary> /// Constrói eretorna o comando SELECT. /// </summary> internal string GetSelectParent(longidParent) { returngetSelect(null, idParent, nameIdParent); } /// <summary> /// Constrói eretorna o comando INSERT. /// </summary> internal string GetInsert() { PropertyInfo[]arrayPropertyInfo = this.GetType().GetProperties(); StringBuilderoStringBuilder = newStringBuilder(); oStringBuilder.Append(String.Format("INSERT INTO .(", this.nameSchema, this.nameTable)); boolisFirstColumn = true; for (int index = 0; index <arrayPropertyInfo.Length; index++) { PropertyInfooPropertyInfo = arrayPropertyInfo[index]; object[]arrayFieldAttribute = oPropertyInfo.GetCustomAttributes(true); if(arrayFieldAttribute.Length > 0) { FieldAttributeoFieldAttribute = (FieldAttribute)arrayFieldAttribute[0]; stringcarac = ","; if(isFirstColumn) { carac = ""; } if(!oFieldAttribute.IsPrimaryKey&& !oFieldAttribute.IsForeignKey &&oFieldAttribute.TypeProperty != TypeProperty.Collection) { oStringBuilder.Append(String.Format("",carac, oFieldAttribute.NameField)); isFirstColumn = false; } } } oStringBuilder.Append(")VALUES("); isFirstColumn =true; for (int index = 0; index <arrayPropertyInfo.Length; index++) { PropertyInfooPropertyInfo = arrayPropertyInfo[index]; object[]arrayFieldAttribute = oPropertyInfo.GetCustomAttributes(true); if(arrayFieldAttribute.Length > 0) { FieldAttributeoFieldAttribute = (FieldAttribute)arrayFieldAttribute[0]; stringcarac = ","; if(isFirstColumn) { carac = ""; } if(!oFieldAttribute.IsPrimaryKey&& !oFieldAttribute.IsForeignKey &&oFieldAttribute.TypeProperty != TypeProperty.Collection) { oStringBuilder.Append(String.Format("",carac, oFieldAttribute.NameParam)); isFirstColumn = false; } } } oStringBuilder.Append(")"); returnoStringBuilder.ToString(); } /// <summary> /// Constrói eretorna o comando UPDATE. /// </summary> internal string GetUpdate() { PropertyInfo[]arrayPropertyInfo = this.GetType().GetProperties(); StringBuilderoStringBuilder = newStringBuilder(); oStringBuilder.Append(String.Format("UPDATE . SET ", this.nameSchema, this.nameTable)); boolisFirstColumn = true; for (int index = 0; index <arrayPropertyInfo.Length; index++) { PropertyInfooPropertyInfo = arrayPropertyInfo[index]; object[]arrayFieldAttribute = oPropertyInfo.GetCustomAttributes(true); if(arrayFieldAttribute.Length > 0) { FieldAttributeoFieldAttribute = (FieldAttribute)arrayFieldAttribute[0]; stringcarac = ","; if(isFirstColumn) { carac = ""; } if(!oFieldAttribute.IsPrimaryKey&& !oFieldAttribute.IsForeignKey &&oFieldAttribute.TypeProperty != TypeProperty.Collection) { oStringBuilder.Append(String.Format(" =", carac, oFieldAttribute.NameField,oFieldAttribute.NameParam)); isFirstColumn = false; } } } oStringBuilder.Append(String.Format(" WHERE bgId = ", this.Id)); return oStringBuilder.ToString(); } /// <summary> /// Constrói eretorna o comando DELETE. /// </summary> internal string GetDelete() { return String.Format("DELETE FROM . WHERE bgId = ", this.nameSchema, this.nameTable, this.Id); } /// <summary> /// Retorna um coleçãode objetos da classe FieldAttribute que vai ser utilizada na classes DAO. /// </summary> internal List<FieldAttribute>GetFieldAttributeCollection() { List<FieldAttribute> fieldAttributeCollection = new List<FieldAttribute>(); PropertyInfo[]arrayPropertyInfo = this.GetType().GetProperties(); for (int index = 0; index <arrayPropertyInfo.Length; index++) { PropertyInfooPropertyInfo = arrayPropertyInfo[index]; object[]arrayFieldAttribute = oPropertyInfo.GetCustomAttributes(true); if(arrayFieldAttribute.Length > 0) { FieldAttributeoFieldAttribute = (FieldAttribute)arrayFieldAttribute[0]; if(!oFieldAttribute.IsForeignKey&& oFieldAttribute.TypeProperty !=TypeProperty.Collection) { if(oFieldAttribute.TypeProperty == TypeProperty.Type) { oFieldAttribute.Value =oPropertyInfo.GetValue(this, null); } elseif (oFieldAttribute.TypeProperty== TypeProperty.Reference) { BaseENoBaseEN = (BaseEN)oPropertyInfo.GetValue(this, null); if(oBaseEN == null) { oFieldAttribute.Value = null; } else { oFieldAttribute.Value =oBaseEN.Id; } } fieldAttributeCollection.Add(oFieldAttribute); } } } returnfieldAttributeCollection; } /// <summary> /// Atribuí osvalores para as propriedades da classe. /// </summary> internal void SetValuesProperties(DataRowoDataRow, int level) { PropertyInfo[]arrayPropertyInfo = this.GetType().GetProperties(); for (int index = 0; index <arrayPropertyInfo.Length; index++) { PropertyInfooPropertyInfo = arrayPropertyInfo[index]; object[]arrayFieldAttribute = oPropertyInfo.GetCustomAttributes(true); if(arrayFieldAttribute.Length > 0) { FieldAttributeoFieldAttribute = (FieldAttribute)arrayFieldAttribute[0]; if(oFieldAttribute.TypeProperty == TypeProperty.Type) { objectvalue = oDataRow[String.Format("__",this.nameSchema,this.nameTable,oFieldAttribute.NameField)]; oPropertyInfo.SetValue(this,value, null); } elseif (oFieldAttribute.TypeProperty== TypeProperty.Reference) { if(level + 1< 2) { AssemblyoAssembly = this.GetType().Assembly; stringnameAssembly = this.GetType().FullName; nameAssembly = nameAssembly.Substring(0, nameAssembly.LastIndexOf('.')); nameAssembly = String.Format(".EN",nameAssembly, oPropertyInfo.PropertyType.Name.Substring(1)); //Cria uma novainstância, passando como parâmetro o objeto da classe FacadeDAO. BaseEN oBaseEN = (BaseEN)oAssembly.CreateInstance(nameAssembly,false, BindingFlags.CreateInstance, null,new object[] { this._oFacadeDAO}, null, null); objectvalueId = oDataRow[String.Format("__bgId",oBaseEN.nameSchema, oBaseEN.nameTable)]; if(valueId != DBNull.Value &&valueId != null) { oPropertyInfo.SetValue(this,oBaseEN, null); oBaseEN.SetValuesProperties(oDataRow, level + 1); } } } } } this.status = StatusObject.Loaded; } /// <summary> /// Monta o comandoSELECT de acordo com as propriedades. /// </summary> private string getSelect(long? id, long? idParent, stringnameIdParent) { PropertyInfo[]arrayPropertyInfo = this.GetType().GetProperties(); StringBuilderoStringBuilder = newStringBuilder(); StringBuilderjoinStringBuilder = newStringBuilder(); oStringBuilder.Append("SELECT "); oStringBuilder.Append(this.getFields()); for (int index = 0; index <arrayPropertyInfo.Length; index++) { PropertyInfooPropertyInfo = arrayPropertyInfo[index]; object[]arrayFieldAttribute = oPropertyInfo.GetCustomAttributes(true); if(arrayFieldAttribute.Length > 0) { FieldAttributeoFieldAttribute = (FieldAttribute)arrayFieldAttribute[0]; if(oFieldAttribute.TypeProperty == TypeProperty.Reference &&!oFieldAttribute.IsForeignKey) { BaseENoBaseEN = (BaseEN)oPropertyInfo.GetValue(this, null); if(oBaseEN == null) { AssemblyoAssembly = this.GetType().Assembly; stringnameAssembly = this.GetType().FullName; nameAssembly = nameAssembly.Substring(0, nameAssembly.LastIndexOf('.')); nameAssembly = String.Format(".EN",nameAssembly, oPropertyInfo.PropertyType.Name.Substring(1)); //Cria uma novainstância, passando como parâmetro o objeto da classe FacadeDAO. oBaseEN= (BaseEN)oAssembly.CreateInstance(nameAssembly, false, BindingFlags.CreateInstance, null,new object[] { this._oFacadeDAO}, null, null); } oStringBuilder.Append(String.Format(",",oBaseEN.getFields())); if(!oFieldAttribute.IsNull) { joinStringBuilder.Append(String.Format(" INNERJOIN . AS _ ON _.bgId = _. ", oBaseEN.nameSchema, oBaseEN.nameTable,this.nameSchema,this.nameTable,oFieldAttribute.NameField)); } else { joinStringBuilder.Append(String.Format(" LEFTJOIN . AS _ ON _.bgId = _. ", oBaseEN.nameSchema, oBaseEN.nameTable,this.nameSchema,this.nameTable,oFieldAttribute.NameField)); } } } } oStringBuilder.Append(String.Format(" FROM . AS _ ", this.nameSchema, this.nameTable)); oStringBuilder.Append(joinStringBuilder.ToString()); if (id != null) { oStringBuilder.Append(String.Format(" WHERE_.bgId = ", this.nameSchema, this.nameTable, id.Value)); } else if (idParent != null) { oStringBuilder.Append(String.Format(" WHERE_. = ", this.nameSchema, this.nameTable, nameIdParent, idParent.Value)); } return oStringBuilder.ToString(); } /// <summary> /// Método que alterao status da classe. /// </summary> protected void InformPropertyChanged() { if (this.status == StatusObject.Loaded) { this.status = StatusObject.Changed; } } /// <summary> /// Retorna os campospara montar o comando SELECT. /// </summary> private string getFields() { PropertyInfo[]arrayPropertyInfo = this.GetType().GetProperties(); StringBuilderoStringBuilder = newStringBuilder(); boolisFirstColumn = true; for (int index = 0; index <arrayPropertyInfo.Length; index++) { PropertyInfooPropertyInfo = arrayPropertyInfo[index]; object[]arrayFieldAttribute = oPropertyInfo.GetCustomAttributes(true); if(arrayFieldAttribute.Length > 0) { FieldAttributeoFieldAttribute = (FieldAttribute)arrayFieldAttribute[0]; stringcarac = ","; if(isFirstColumn) { carac = ""; } if(!oFieldAttribute.IsForeignKey&& oFieldAttribute.TypeProperty !=TypeProperty.Collection) { oStringBuilder.Append(String.Format("_.AS __", carac, this.nameSchema, this.nameTable, oFieldAttribute.NameField)); isFirstColumn = false; } } } returnoStringBuilder.ToString(); } } }

As classes entidades vamos configurar dessa forma.

Quando uma propriedade é um tipo.

[FieldAttribute(false, false, TypeProperty.Type,"vcName", "@vcName",150, System.Data.DbType.String, false)] public stringName { get { return _name; } set { _name = value; base.InformPropertyChanged();} }

Quando uma propriedade é uma referência. É criado uma propriedade com o tipo Int64 e outra com o tipo da classe. Quando os valores são atribuídos a classe, o método só preenche as propriedade da classe e com as classes que estão relacionadas.Ex:

A classe Marido está relacionada com a classe Esposa, a classe Esposa está com a classe está relacionada com a classe Cunhada, no momento do preenchimento as classes que serão preenchidas serão a classe Marido e a classe Esposa, a classe Cunhada só será preenchida quando for acessada (Esposa.Cunhada).

É quando vamos utilizar a propriedade Int64 que contém o id da classe que não foi preenchida.

[FieldAttribute(false, true, TypeProperty.Type,"bgIdCunhada", "@bgIdCunhada", 0,System.Data.DbType.Int64, false)] public Int64oIdCunhada { get { return _oIdCunhada; } set {_oIdCunhada = value;} } [FieldAttribute(false, false, TypeProperty.Reference,"bgIdCunhada", "@bgIdCunhada", 0,System.Data.DbType.Int64, false)] publicICunhada oCunhada { get { if ((_oCunhada ==null ||_oCunhada.Id ==0) &&this.oIdCunhada> 0) { _oCunhada = (CunhadaEN)new Persistencia.DAO.CunhadaDAO(base.oFacadeDAO).Read(this.oIdCunhada); } return _oCunhada; } set { _oCunhada =(CunhadaEN)value;base.InformPropertyChanged();} }

Quando uma propriedade é uma coleção.

[FieldAttribute(false, false, TypeProperty.Collection,"", "@",0, System.Data.DbType.Int64, false)] public List<IFilho> FilhoCollection { get { return _filhoCollection; } set {_filhoCollection = value;base.InformPropertyChanged();} }

No construtor da classe vamos passar o nome do schema, nome da tabela e o objeto da classe FacadeDAO.

publicTabelaEN(FacadeDAO oFacadeDAO) : base("dbo","tbTabela", oFacadeDAO) { }

Aqui é estrutura da classe entidade.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Persistencia.EN.Base; using Persistencia.EN.Interface; namespace Persistencia.EN { internal sealed class EsposaEN : BaseEN,IEsposa { private string _name; private Int64 _oIdCunhada; private CunhadaEN_oCunhada; private List<IFilho> _filhoCollection; public StatusObject StatusObjeto { get { return base.GetStatus(); } } [FieldAttribute(false, false, TypeProperty.Type,"vcName", "@vcName",150, System.Data.DbType.String, false)] public string Name { get { return _name; } set {_name = value;base.InformPropertyChanged();} } [FieldAttribute(false, true, TypeProperty.Type,"bgIdCunhada", "@bgIdCunhada", 0,System.Data.DbType.Int64, false)] public Int64 oIdCunhada { get { return _oIdCunhada; } set {_oIdCunhada = value;} } [FieldAttribute(false, false, TypeProperty.Reference,"bgIdCunhada", "@bgIdCunhada", 0,System.Data.DbType.Int64, false)] public ICunhada oCunhada { get { if ((_oCunhada ==null ||_oCunhada.Id ==0) &&this.oIdCunhada> 0) { _oCunhada = (CunhadaEN)new Persistencia.DAO.CunhadaDAO(base.oFacadeDAO).Read(this.oIdCunhada); } return _oCunhada; } set { _oCunhada =(CunhadaEN)value;base.InformPropertyChanged();} } [FieldAttribute(false, false, TypeProperty.Collection,"", "@",0, System.Data.DbType.Int64, false)] public List<IFilho>FilhoCollection { get { return _filhoCollection; } set {_filhoCollection = value;base.InformPropertyChanged();} } public EsposaEN(FacadeDAOoFacadeDAO) : base("dbo","tbEsposa", oFacadeDAO)//public = Caso for usar o postgresql { } } }

Aqui é estrutura da interface.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Persistencia.EN.Base; namespace Persistencia.EN.Interface { public interface IEsposa { StatusObjectStatusObjeto { get; } Int64 Id{ get; } string Name{ get; set; } ICunhadaoCunhada { get; set;} List<IFilho> FilhoCollection { get;set; } void Remove(); void UnRemove(); } }

No pacote DAO foi criada uma classe abstrata BaseDAO.

Os métodos públicos da classe:

Write<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'=""> = identifica o status da classe e chama o método que corresponde ao status.
Read = carrega o objeto com os dados do banco de dados.</spanstyle='font-size:12.0pt;font-family:"times>

ReadAll<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'=""> = carrega uma coleção com os dados do banco de dados.</spanstyle='font-size:12.0pt;font-family:"times>

ReadAllParent<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'=""> = carrega uma coleção com os dados do banco de dados, utilizado quando a classe tem filhos.</spanstyle='font-size:12.0pt;font-family:"times>

Os métodos privados da classe:

insert<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'=""> = grava um novo registro no banco de dados.</spanstyle='font-size:12.0pt;font-family:"times>

update<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'=""> = atualiza o registro no banco de dados.</spanstyle='font-size:12.0pt;font-family:"times>

delete<spanstyle='font-size:12.0pt;font-family:"times new="" roman","serif"'=""> = exclui o registro no banco de dados.</spanstyle='font-size:12.0pt;font-family:"times>

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using Persistencia.EN.Base; using Persistencia.Data.Base; namespace Persistencia.DAO.Base { class BaseDAO { /// <summary> /// Escreve no bancode dados /// </summary> protected void Write(DatabaseoDatabase, BaseEN oBaseEN) { StatusObject status = oBaseEN.GetStatus(); if(status == StatusObject.New) { insert(oDatabase, oBaseEN); } else if (status ==StatusObject.Changed) { update(oDatabase, oBaseEN); } else if (status ==StatusObject.DeletedChanged || status ==StatusObject.DeletedLoaded) { delete(oDatabase, oBaseEN); } } /// <summary> /// Lê o registro nobanco de dados /// </summary> protected void Read(DatabaseoDatabase, BaseEN oBaseEN, long id) { DataRowoDataRow = oDatabase.ExecuteDataRow(oBaseEN.GetSelect(id)); if(oDataRow != null) { oBaseEN.SetValuesProperties(oDataRow,0); } else { oBaseEN = null; } } /// <summary> /// Lê uma coleção deregistros no banco de dados. /// </summary> protected void ReadAll(DatabaseoDatabase, BaseEN oBaseEN, Action<BaseEN>action) { DataTableoDataTable = oDatabase.ExecuteDataAdapter_DataTable(oBaseEN.GetSelect()); for (int index = 0; index <oDataTable.Rows.Count;index++) { BaseENnewBaseEN = oBaseEN.NewInstance(); newBaseEN.SetValuesProperties(oDataTable.Rows[index], 0); action(newBaseEN); } } /// <summary> /// Lê uma coleção deregistro no banco de dados, utilizado quando a classe tem filhos. /// </summary> protected void ReadAllParent(DatabaseoDatabase, BaseEN oBaseEN, long idParent, Action<BaseEN> action) { DataTableoDataTable = oDatabase.ExecuteDataAdapter_DataTable(oBaseEN.GetSelectParent(idParent)); for (int index = 0; index <oDataTable.Rows.Count;index++) { BaseENnewBaseEN = oBaseEN.NewInstance(); newBaseEN.SetValuesProperties(oDataTable.Rows[index], 0); action(newBaseEN); } } /// <summary> /// Insere o registrono banco de dados. /// </summary> private void insert(DatabaseoDatabase, BaseEN oBaseEN) { List<IDbDataParameter> parameterCollection =new List<IDbDataParameter>(); oBaseEN.GetFieldAttributeCollection().ForEach(delegate(FieldAttribute item){ IDbDataParameteroIDbDataParameter = oDatabase.CreateObjectParameter(item.IsNull); oIDbDataParameter.SourceColumn =item.NameField; oIDbDataParameter.ParameterName =item.NameParam; oIDbDataParameter.Size = item.Length; oIDbDataParameter.Precision =item.Precision; oIDbDataParameter.Scale = item.Scale; oIDbDataParameter.DbType = item.DbType; oIDbDataParameter.Value = item.Value; parameterCollection.Add(oIDbDataParameter); }); objectid = oDatabase.ExecuteScalar(String.Format(";", oBaseEN.GetInsert(), oDatabase.CommandLastIdentity()),parameterCollection); oBaseEN.Id= long.Parse(id.ToString()); } /// <summary> /// Atualiza oregistro no banco de dados. /// </summary> private void update(DatabaseoDatabase, BaseEN oBaseEN) { List<IDbDataParameter> parameterCollection =new List<IDbDataParameter>(); oBaseEN.GetFieldAttributeCollection().ForEach(delegate(FieldAttribute item){ IDbDataParameteroIDbDataParameter = oDatabase.CreateObjectParameter(item.IsNull); oIDbDataParameter.SourceColumn =item.NameField; oIDbDataParameter.ParameterName =item.NameParam; oIDbDataParameter.Size = item.Length; oIDbDataParameter.Precision =item.Precision; oIDbDataParameter.Scale = item.Scale; oIDbDataParameter.DbType = item.DbType; oIDbDataParameter.Value = item.Value; parameterCollection.Add(oIDbDataParameter); }); oDatabase.ExecuteNonQuery(oBaseEN.GetUpdate(), parameterCollection); } /// <summary> /// Exclui o registrono banco de dados. /// </summary> private void delete(DatabaseoDatabase, BaseEN oBaseEN) { oDatabase.ExecuteNonQuery(oBaseEN.GetDelete()); } } }

Aqui é estrutura de uma classe DAO que não tem filhos.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Persistencia.DAO.Base; using Persistencia.EN; using Persistencia.EN.Interface; using Persistencia.EN.Base; using Persistencia.Data.Base; namespace Persistencia.DAO { class CunhadaDAO : BaseDAO { private FacadeDAO oFacadeDAO; publicCunhadaDAO(FacadeDAO oFacadeDAO) { this.oFacadeDAO =oFacadeDAO; } public voidWrite(ICunhada oCunhada) { DatabaseoDatabase = oFacadeDAO.CreateInstanceDatabase(); try { oDatabase.ConnectionOpen(oFacadeDAO.GetStringConnection()); base.Write(oDatabase, (CunhadaEN)oCunhada); oDatabase.ConnectionClose(); } catch (Exception oException) { oDatabase.ConnectionClose(); throwoException; } } public ICunhada Read(longid) { CunhadaEN oCunhadaEN = new CunhadaEN(oFacadeDAO); Database oDatabase =oFacadeDAO.CreateInstanceDatabase(); try { oDatabase.ConnectionOpen(oFacadeDAO.GetStringConnection()); base.Read(oDatabase, oCunhadaEN, id); oDatabase.ConnectionClose(); } catch (Exception oException) { oDatabase.ConnectionClose(); throwoException; } returnoCunhadaEN; } public List<ICunhada>ReadAll() { List<ICunhada> cunhadaCollection =new List<ICunhada>(); DatabaseoDatabase = oFacadeDAO.CreateInstanceDatabase(); try { oDatabase.ConnectionOpen(oFacadeDAO.GetStringConnection()); base.ReadAll(oDatabase, newCunhadaEN(this.oFacadeDAO), delegate(BaseEN itemBase){ cunhadaCollection.Add((CunhadaEN)itemBase); }); oDatabase.ConnectionClose(); } catch (Exception oException) { oDatabase.ConnectionClose(); throwoException; } returncunhadaCollection; } } }

Aqui é estrutura de uma classe DAO que tem filhos.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Persistencia.DAO.Base; using Persistencia.EN; using Persistencia.EN.Interface; using Persistencia.EN.Base; using Persistencia.Data.Base; namespace Persistencia.DAO { class EsposaDAO : BaseDAO { private FacadeDAO oFacadeDAO; publicEsposaDAO(FacadeDAO oFacadeDAO) { this.oFacadeDAO =oFacadeDAO; } public void Write(IEsposaoEsposa) { DatabaseoDatabase = oFacadeDAO.CreateInstanceDatabase(); try { oDatabase.ConnectionOpen(oFacadeDAO.GetStringConnection()); oDatabase.BeginTransacTion(); base.Write(oDatabase, (EsposaEN)oEsposa); if(oEsposa.FilhoCollection != null) { oEsposa.FilhoCollection.ForEach(delegate(IFilho oFilho){ base.Write(oDatabase, (FilhoEN)oFilho); }); } oDatabase.ComitTransacTion(); oDatabase.ConnectionClose(); } catch (Exception oException) { oDatabase.RollBack(); oDatabase.ConnectionClose(); throwoException; } } public IEsposa Read(longid) { EsposaENoEsposaEN = newEsposaEN(oFacadeDAO); DatabaseoDatabase = oFacadeDAO.CreateInstanceDatabase(); try { oDatabase.ConnectionOpen(oFacadeDAO.GetStringConnection()); base.Read(oDatabase, oEsposaEN, id); if(oEsposaEN != null&& oEsposaEN.Id!= 0) { oEsposaEN.FilhoCollection = readAllFilho(oDatabase, oEsposaEN); oEsposaEN.SetStatus(StatusObject.Loaded);//Aqui estouforçando o status da classe para objeto carregado. Só acontece quando a classetem filhos. } else { oEsposaEN = null; } oDatabase.ConnectionClose(); } catch (Exception oException) { oDatabase.ConnectionClose(); throwoException; } returnoEsposaEN; } public List<IEsposa>ReadAll() { List<IEsposa> esposaCollection =new List<IEsposa>(); DatabaseoDatabase = oFacadeDAO.CreateInstanceDatabase(); try { oDatabase.ConnectionOpen(oFacadeDAO.GetStringConnection()); base.ReadAll(oDatabase, newEsposaEN(this.oFacadeDAO), delegate(BaseEN itemBase){ EsposaEN oEsposa = (EsposaEN)itemBase; oEsposa.FilhoCollection = readAllFilho(oDatabase, oEsposa); oEsposa.SetStatus(StatusObject.Loaded);//Aqui estouforçando o status da classe para objeto carregado. Só acontece quando a classetem filhos. esposaCollection.Add(oEsposa); }); oDatabase.ConnectionClose(); } catch (Exception oException) { oDatabase.ConnectionClose(); throwoException; } returnesposaCollection; } private List<IFilho> readAllFilho(DatabaseoDatabase, EsposaEN oEsposa) { List<IFilho> filhoCollection =new List<IFilho>(); base.ReadAllParent(oDatabase, newFilhoEN(this.oFacadeDAO), oEsposa.Id,delegate(BaseENitemBase){ FilhoEN oFilho =(FilhoEN)itemBase; oFilho.oEsposa =oEsposa; filhoCollection.Add(oFilho); }); returnfilhoCollection; } } }

Como reflection não precisamos criar os comandos Sql e nem precisamos ficar programando para preencher as propriedades da classe.

Até o próximo artigo.

Artigos relacionados