/// <summary> /// Encontra todos os registos que satisfaçam a condição /// </summary> /// <param name="w">condição para buscar os registros</param> /// <param name="whereParameters">Parâmetros utilizados na clausula where</param> /// <param name="model">Modelo base</param> /// <typeparam name="T">Tipo de modelo que deverá ser retornado</typeparam> /// <returns></returns> public static List <T> Find <T>(T model, IEnumerable <Parameter> whereParameters = null, Where w = null) where T : IBaseModel { List <T> result = new List <T>(); try { model.Connection = DbContext.CreateConnection(); TableDefinitionAttribute tableDefinition = FindTableDefinition(model); //recuperar o campo GUID da tabela mais básica Command command = new Command(); new CommandFactory(model).PrepareCommandSelect(tableDefinition, w, null, whereParameters, ref command); command.Connection = model.Connection; DataReader dataReader = command.ExecuteReader(); while (dataReader.Read()) { model.Populate(dataReader); result.Add(model); } } finally { model.Connection.Close(); } return(result); }
private static string GetTableName(object table) { var tableQuery = (IQueryable)table; var rowType = tableQuery.ElementType; return(TableDefinitionAttribute.ClassTableName(rowType) ?? rowType.Name); }
/// <summary> /// Prepara os valores e retorna os em um formato de exibição para o usuário /// <para>Como padrão retorna os três primeiros campos do select que foi criado</para> /// </summary> /// <param name="w">Filtro, se necessário. Não é obrigatório e pode ser nulo</param> /// <param name="model">Modelo base</param> /// <typeparam name="T">Tipo de modelo que deverá ser retornado</typeparam> /// <param name="pageSize">Tamanho da página de registros</param> /// <param name="executeCommand">Se true, irá executar o comando e retornar os dados</param> /// <returns>Retorna os valores em um um formato de exibição para o usuário</returns> public static IDisplayValues GetDisplayValues(IParentModel model, Where w = null, bool executeCommand = true, int pageSize = 100) { if (w == null) { w = new Where { Limit = pageSize } } ; IDisplayValues result = new DisplayValues(model); DataReader dataReader = null; try { model.Connection = DbContext.CreateConnection(); TableDefinitionAttribute tableDefinition = FindTableDefinition(model); //recuperar o campo GUID da tabela mais básica Command command = new Command(); new CommandFactory(model).PrepareCommandSelect(tableDefinition, w, null, null, ref command); command.Connection = model.Connection; dataReader = executeCommand ? command.ExecuteReader() : command.ExecuteReader(System.Data.CommandBehavior.SchemaOnly); } finally { model.Connection.Close(); } result.Where = w; result.DataReader = dataReader; return(result); }
public static EGUID Create(this EGUID eguid, IBaseModel model, TableDefinitionAttribute tableDefinition, IEmpresa empresa = null) { #if !IsPAF //------------------------------------------------------------------------- // Se o EGUID já foi informado, descartar as condições abaixo. // Isso pode dar erros nas importações se for modificado. // Pode dar erros nas integrações entre DAV/PV // Pode dar erros em todos os lugares que usam a condição EGUID = ?? // Modifique a condição abaixo apenas se souber o que está fazendo //------------------------------------------------------------------------- // if(!eguid.IsNullOrEmpty()) // return eguid; #endif EGUID result = EGUID.Empty; string tableName = tableDefinition.TableName; if (model is Model.Faturamento.Lancamento.Movimento.NFCe.INFCe && eguid.IsNullOrEmpty()) tableName = "fat_LanMovNFCe"; else if (model is Model.Faturamento.Lancamento.Movimento.NFe.INFe && eguid.IsNullOrEmpty()) tableName = "fat_LanMovNFe"; IConfiguracaoEGUID conf = new ConfiguracaoEGUID(tableName); switch(conf.UsoEGUID) { case Enuns.Configuracao.UsoEGUID.Custom: if(conf.Code.StartsWith("code={", StringComparison.CurrentCultureIgnoreCase)) { string s = conf.Code.Substring(6); s = "public object GetEGUID(object value){" + s.Substring(0, s.Length - 1) + "}"; Assembly assembly = Compiler.Compiler.Compile(Code.Builder.Build("OpenPOS", "OpenPOSEGUIDConfiguracao", s)); result = Compiler.Compiler.Invoke("OpenPOS.OpenPOSEGUIDConfiguracao", "GetEGUID", assembly, new object[] { eguid }).ToString(); } break; case Enuns.Configuracao.UsoEGUID.PorEmpresa: //TODO: Aqui temos que melhorar, pois temos que filtrar pela empresa atual, e // Se não encontrada deve-se criar um para a empresa atual. conf.Numero += 1; result = conf.Numero.ToString(); break; case Enuns.Configuracao.UsoEGUID.PorTabela: conf.Numero += 1; result = conf.Numero.ToString(); break; case Enuns.Configuracao.UsoEGUID.Default: default: result = eguid.IsNullOrEmpty() ? new Random().Next().ToString() : Convert.ToString(eguid); break; } if(!String.IsNullOrEmpty(conf.Mascara)) result = conf.Numero.ToString(conf.Mascara); conf.Save(); return result; }
public void TestTableNameAttribute() { var results = TableDefinitionAttribute.ClassTableName(typeof(DbClassLibrary.ActiveRecords.Employee)); Assert.IsNotEmpty(results); Assert.IsNull(TableDefinitionAttribute.ClassTableName(typeof(Employees))); Console.WriteLine(results); }
/// <summary> /// Cria um parâmetro com base nas informações passadas e retorna /// </summary> /// <param name="tableDefinition">Definição da tabela</param> /// <param name="item">Item de propriedade para recuperar os nomes e informações do campo.</param> /// <param name="insert">Se true, os parâmetros fields e values estarão preparados para o insert, caso contrário, update</param> /// <returns></returns> private Parameter CreateParameter(TableDefinitionAttribute tableDefinition, PropertyInfo item, bool insert) { string parameterName; string fieldName = GetFieldName(item, tableDefinition, false); parameterName = GetParameterName(item); object value = item.GetValue(model, null); return(CreateParameter(fieldName, parameterName, value, insert)); }
protected virtual object GetUpdateWhere(Command command, IID id) { object[] attribs = currentType.GetCustomAttributes(typeof(TableDefinitionAttribute), false); TableDefinitionAttribute a = attribs[0] as TableDefinitionAttribute; command.Parameters.Add(new Parameter("@" + a.PrimaryKey, GenericDbType.String) { SourceColumn = a.PrimaryKey, Value = id.ConvertToDbValue() }); return(string.Format("{0} = @{0}", a.PrimaryKey)); }
/// <summary> /// Retorna um registro pelo GUID. Null se não encontrar nada /// </summary> /// <param name="id">identificador do registro</param> /// <returns></returns> public static IBaseModel Get(object id, IBaseModel model) { TableDefinitionAttribute tableDefinition = FindTableDefinition(model); Where w = new Where(); w.Add(tableDefinition.PrimaryKey, id.ToString()); IList <IBaseModel> result = Find(model, w); if (result.Count > 0) { return(result[0]); } return(null); }
/// <summary> /// Preenche o modelo com o primeiro registro encontrado /// </summary> ///<param name="model">Model que deverá ser populado</param> ///<param name="w">Filtro para pesquisar os registros</param> /// <returns></returns> public static void Populate(IBaseModel model, Where w) { try { model.Connection = DbContext.CreateConnection(); TableDefinitionAttribute tableDefinition = null; //recuperar o campo ID da tabela mais básica tableDefinition = FindTableDefinition(model); Command command = new Command(); new CommandFactory(model).PrepareCommandSelect(tableDefinition, w, null, null, ref command); command.Connection = model.Connection; Populate(model, command.ExecuteReader()); } finally { model.Connection.Close(); } }
public Command CreateCommandDelete(TableDefinitionAttribute tableDefinition, IID id) { Command command = connection.CreateCommand(); command.Transaction = transaction; string pkName = GetPKName(tableDefinition); string commandText = ""; commandText = string.Format("DELETE FROM {0} WHERE {1} = @where_1;", tableDefinition.TableName, pkName); command.CommandText = commandText; command.Parameters.Add(new Parameter("@where_1", GenericDbType.String) { SourceColumn = pkName, Value = id.ToString() }); return(command); }
/// <summary> /// Encontra todos os registos que satisfaçam a condição /// </summary> /// <param name="w">condição para buscar os registros</param> /// <param name="model">Modelo base</param> /// <typeparam name="T">Tipo de modelo que deverá ser retornado</typeparam> /// <param name="connection">Conexão que será utilizada para buscar os dados</param> /// <returns></returns> public static List <T> Find <T>(T model, Connection connection, Where w) where T : IBaseModel { List <T> result = new List <T>(); IList <IID> ids = new List <IID>(); try { connection.Open(); model.Connection = connection; TableDefinitionAttribute tableDefinition = FindTableDefinition(model); //recuperar o campo GUID da tabela mais básica Command command = new Command(); new CommandFactory(model).PrepareCommandSelect(tableDefinition, w, null, null, ref command); command.Connection = model.Connection; DataReader dataReader = command.ExecuteReader(); while (dataReader.Read()) { if (model is IParentModel) { IID id = Utilities.DbUtils.GetPrimaryKeyValue(model); if (ids.Contains(id)) { continue; } ids.Add(id); } model.Populate(dataReader); result.Add(model); } } finally { connection.Close(); } return(result); }
private bool CanUseField(System.Reflection.PropertyInfo item, TableDefinitionAttribute tableDefinition) { //valida se pode usar este campo object[] attribs = item.GetCustomAttributes(typeof(FieldDefinitionAttribute), false); if (attribs.Count() > 0) { if (!(attribs[0] as FieldDefinitionAttribute).IsTableField) { return(false); } } //recupera o nome do campo string fieldName = GetFieldName(item, tableDefinition); //se o campo for a chave primária não pode ser usado if (!tableDefinition.UseInsert && fieldName.Equals(GetPKName(tableDefinition), StringComparison.InvariantCultureIgnoreCase)) { return(false); } return(true); }
/// <summary> /// Exclui um registro da base de dados /// </summary> /// <param name="id">identificador do registro</param> public static void Delete(IID id, IBaseModel model) { try { model.Connection = DbContext.CreateConnection(); model.Connection.BeginTransaction(); //Validar model.ValidateDelete(); TableDefinitionAttribute tableDefinition = FindTableDefinition(model); CommandFactory cf = new CommandFactory(model.Connection, model.Connection.Transaction, model.GetType(), model, null); using (Command command = cf.CreateCommandDelete(tableDefinition, id)) { command.ExecuteNonQuery(); } model.Connection.CommitTransaction(); } catch { model.Connection.RollbackTransaction(); throw; } finally { if (model.Connection != null) { model.Connection.Close(); } } }
private string GetFieldName(System.Reflection.PropertyInfo item, TableDefinitionAttribute tableDefinition, bool withTableName) { object[] attribs = item.GetCustomAttributes(typeof(FieldDefinitionAttribute), false); string name = ""; string table = ""; if (attribs.Count() > 0) { FieldDefinitionAttribute f = attribs[0] as FieldDefinitionAttribute; if (f.IsJoinField) { table = f.JoinTable; name = f.FieldName; } else { table = tableDefinition.TableName; name = f.FieldName; } } else { table = tableDefinition.TableName; name = item.Name; } if (withTableName) { return(string.Format("{0}.{1}", table, name)); } return(name); }
private string GetPKName(TableDefinitionAttribute tableDefinition) { //recupera a definição da tabela return(string.Format("{0}.{1}", tableDefinition.TableName, tableDefinition.PrimaryKey)); }
/// <summary> /// Salva o registro na base de dados /// </summary> /// <param name="model"></param> public static IID Save(IBaseModel model) { IID result = null; bool oldNew = model.New; IID fk = null; ForeignKeys foreignKeys = new ForeignKeys(); bool inserting = false; IEnumerable <MyHierarchicalType> models = null; TableDefinitionAttribute tableDefinition = null; try { //se este model for do tipo IChildModel //deve-se usar a conexão do Parent e cria uma foreignKey if (model.IsChildModel()) { dynamic m = model; if (m.Parent != null) { model.Connection = m.Parent.Connection; models = Utilities.DbUtils.GetModels(m.Parent as IBaseModel); foreach (var modelType in models) { if (modelType.Type.GetCustomAttributes(typeof(TableDefinitionAttribute), false).Count() > 0) { tableDefinition = modelType.Type.GetCustomAttributes(typeof(TableDefinitionAttribute), false)[0] as TableDefinitionAttribute; fk = Utilities.DbUtils.GetPrimaryKeyValue(m); //adicionar o foreign key, se necessário usar no command foreignKeys.Add(tableDefinition.TableName, fk); } } } } model.Connection.Open(); model.Connection.BeginTransaction(); //Detectar se é uma inserção //se o modelo é marcado como não atualizável, deverá sempre sofrer insert object[] notUpdatable = model.GetType().GetCustomAttributes(typeof(NotUpdatableAttribute), true); inserting = notUpdatable.Count() > 0 || model.New; //Validar model.Validate(!inserting); model.BeforeSave(!inserting); //revalidar o insert, pois pode ter sido modificado pelo Validate e BeforeSave inserting = notUpdatable.Count() > 0 || model.New; models = Utilities.DbUtils.GetModels(model); //para todos os modelos retornados, iremos buscar as tabelas que compoe estes modelos foreach (var modelType in models.OrderByDescending(o => o.Order)) { if (modelType.Type.GetCustomAttributes(typeof(TableDefinitionAttribute), false).Count() > 0) { tableDefinition = modelType.Type.GetCustomAttributes(typeof(TableDefinitionAttribute), false)[0] as TableDefinitionAttribute; CommandFactory cf = new CommandFactory(model.Connection, model.Connection.Transaction, modelType.Type, model, foreignKeys); using (Command command = cf.CreateCommand(inserting)) { //Preparar o comando antes de executar model.PrepareCommand(command, !inserting); //executar o comando command.ExecuteNonQuery(); //se esta tabela possuir GUID, deverá ser armazenada para referência como chave estrangeira if (Utilities.DbUtils.Tables[tableDefinition.TableName].Fields.Contains(tableDefinition.PrimaryKey)) { fk = Utilities.DbUtils.GetPrimaryKeyValue(model); } if (!result.IsValid()) { result = fk; } //adicionar o foreign key, se necessário usar no command foreignKeys.Add(tableDefinition.TableName, fk); } } } model.AfterSave(!inserting); model.Connection.CommitTransaction(); model.New = false; } catch { model.Connection.RollbackTransaction(); model.New = oldNew; throw; } finally { model.Connection.Close(); } model.New = false; return(result); }
private string GetFieldName(System.Reflection.PropertyInfo item, TableDefinitionAttribute tableDefinition) { return(GetFieldName(item, tableDefinition, true)); }
public virtual Command CreateCommand(bool insert) { string commandText = ""; Command command = connection.CreateCommand(); command.Transaction = transaction; string[] fields; string[] values; //aqui iremos determinar quais os objetos que irão compor este comando TableDefinitionAttribute tableDefinition = currentType.GetCustomAttributes(typeof(TableDefinitionAttribute), false)[0] as TableDefinitionAttribute; commandText += "{command} {tablename} {command2};"; //aqui não podemos filtrar as propriedades apenas pela instancia, pois as mesmas podem vir de heranças var props = currentType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(p => { //--------------------------------------------------------------------------- // garantir que apenas os campos desta tabela sejam passadas como propriedade // Podem estar vindo de uma herança //--------------------------------------------------------------------------- string fieldName = GetFieldName(p, tableDefinition, false); return(tableDefinition.Fields.Contains(fieldName)); }); if (BeforeCreateCommandAction != null) { BeforeCreateCommandAction(command); } #region Campos foreach (var item in props) { if (CanUseField(item, tableDefinition)) { command.Parameters.Add(CreateParameter(tableDefinition, item, insert)); } } #endregion #region Default Values IList <DefaultValueAttribute> defaultValues = (from x in currentType.GetCustomAttributes(typeof(DefaultValueAttribute), false) select x as DefaultValueAttribute).ToList <DefaultValueAttribute>(); if (defaultValues.Count > 0) { foreach (DefaultValueAttribute defaultValue in defaultValues) { command.Parameters.Add(CreateParameter(defaultValue.FieldName, "@" + defaultValue.FieldName, defaultValue.Value, insert)); } } #endregion #region chaves estrangeiras //na nossa aplicação usamos o GUID como pk e sempre temos ter as chaves estrangeiras que serão do tipo inteiro //recuperar a fk ForeignKeyAttribute[] fks = GetForeignKey(); //para cada um retornado, temos que validar se existe na definição if (fks != null) { foreach (ForeignKeyAttribute fk in fks.Where(f => //--------------------------------------------------------------------------- // garantir que apenas os campos desta tabela sejam passadas como propriedade // Podem estar vindo de uma herança //--------------------------------------------------------------------------- tableDefinition.Fields.Contains(f.ForeignKey) && foreignKeys.ContainsKey(f.TableName))) { string fieldName = fk.ForeignKey; string parameterName = "@" + fk.ForeignKey; object value = foreignKeys[fk.TableName]; command.Parameters.Add(CreateParameter(fieldName, parameterName, value, insert)); } } #endregion #region fields/ values fields = new string[command.Parameters.Count]; values = new string[command.Parameters.Count]; #endregion #region insert if (insert) { for (int i = 0; i < command.Parameters.Count; i++) { fields[i] = command.Parameters[i].SourceColumn; values[i] = command.Parameters[i].ParameterName; } commandText = commandText .Replace("{command}", "INSERT INTO") .Replace("{command2}", "(" + fields.Join() + ") VALUES (" + values.Join() + ")") .Replace("{tablename}", tableDefinition.TableName.ToLower()); } #endregion #region update else { for (int i = 0; i < command.Parameters.Count; i++) { fields[i] = String.Format("{0} = {1}", command.Parameters[i].SourceColumn, command.Parameters[i].ParameterName); } commandText = "UPDATE {0} SET {1} WHERE {2}"; commandText = string.Format(commandText, tableDefinition.TableName, fields.Join(), GetUpdateWhere(command, Utilities.DbUtils.GetPrimaryKeyValue(model))); } #endregion command.CommandText = commandText; return(command); }
internal void PrepareCommandSelect(TableDefinitionAttribute tableDefinition, Where where, OrderBy order, IEnumerable <DbParameter> whereParameters, ref Command command) { #region Variáveis string sqlWhere = ""; var props = model.GetType().GetProperties(); //------------------------------------------------------------------------- // Salva os campos que já foram adicionados para não adicionar novamente //------------------------------------------------------------------------- Dictionary <string, SelectField> fields = new Dictionary <string, SelectField>(); string commandText = ""; string selectFields = ""; commandText = @"SELECT {selectFields} {from} {where} {limit}"; if (where == null) { where = new Where(); } #endregion #region Select foreach (MyHierarchicalType hType in Utilities.DbUtils.GetModels(model).OrderByDescending(o => o.Order)) { //recuperar todos os selectedsFields IList <SelectField> selectList = GetSelectAux(hType.Type); if (selectList != null) { foreach (SelectField item in selectList) { if (!fields.ContainsKey(item.FieldAlias)) { selectFields += item.ToString() + ","; fields.Add(item.FieldAlias, item); } } } } if (BeforePrepareSelectAction != null) { BeforePrepareSelectAction(command, selectFields); } selectFields = selectFields.Trim(); if (!string.IsNullOrEmpty(selectFields)) { selectFields = selectFields.Substring(0, selectFields.Length - 1); } #region where if (whereParameters != null && whereParameters.Count() > 0) { foreach (Parameter item in whereParameters) { command.Parameters.Add(item); } } model.PrepareReader(command, where); if (where.Count > 0) { sqlWhere = " WHERE " + where.ToString(); foreach (Parameter p in where.Parameters) { command.Parameters.Add(p); } } #endregion #endregion #region Return commandText = commandText.Replace("{from}", GetFrom()) .Replace("{selectFields}", selectFields) .Replace("{where}", sqlWhere) .Replace("{limit}", where.Limit.ToString()); command.CommandText = commandText; #endregion }