Few notes about naming conventions (I do not repeat for each method/class but they apply to all of them).
EntitiesLayer does not help to categorize your code. Namespace are hierarchical and here you're not using them in that way. Obviously it's not mandatory but something like
Juan.AwesomeProduct.Presentation may help you to organize your code. I am shameless and I admit that at the very beginning (with Managed Extensions for C++, you're lucky if you never had to use it) I used namespaces like you're doing and I still regret.
ECategoria should not be prefixed with
C or anything else.) That's what namespaces are for.
Idcategoria is a public property then it should be PascalCase
idcategoria is underscore prefixed but
categoria are not. Pick a convention (with or without prefix) but be consistent. There are good reasons both to use it or to avoid it, have an informed decision and don't look back.
You're not validating any value in your entities layer. Is acceptable to have
Descripcion? A negative ID? A blank string?
I see no reason for
ECategoria to do not be
Also take care of indentation.
DCategoria (again, remove that prefix) is an utility class. More often than not you do not need it. Its responsibility may be moved to another class that does something else. It may also be a generic class for many entities. Something like a repository, reconsider that name. Also consider to make it
sealed (do you want to extend it through inheritance? Where extension points are?)
Usually underscore is not used to separate words,
Act_Categoria() should be PascalCase (it's a public method) then
ActCategoria() may be more appropriate. However you're mixing two languages. Use English or your own language but do not mix them in code. If you can you may write everything in English and keep comments in your own language (if you work in an company they should have a procedure for this.)
ds are declared at the beginning of your method. In C# you can (and you should) declare them as late as possible. Ideally in the same moment you initialize them. Let's see a proof of concept which also includes some others tips:
public string Act_Categoria(ECategoria categoria)
var parameters = new Dictionary<string, object>();
const string query = "SP_ACTCATEGORIA";
var ds = dbconnection.execute_query(query, parameters);
return ds == null ? "Error Insertando" : "REGISTRO REGISTRADO/ACTUALIZADO EXITOSAMENTE";
catch (Exception ex)
Note that you're catching
Exception. It's a very bad thing to do (I won't repeat here the reasons, do a quick search of check any of my previous reviews here.) Catch the exceptions you know may happen and you want to ignore.
NullReferenceException is a programming error, not a run-time transitory error condition you may want to swallow.
In your business layer
data_categoria may be
readonly. In this moment and with this code I do not see any reason to have a
BCategoria class. It just forwards calls to
DCategoria. Drop one of them until you will actually need it. Business logic should add some value, what's the value of a tunnel? You still expose the same model (
ECategoria) and you just forward calls. In a somehow simple scenario you may merge business layer and data layer but when things are more complex the business layer should have its own model (it is the model...) I'd suggest to do not make things complicate if unnecessary, maybe a 2-tiers architecture is what you should start with.
Presentation layer is just a proof of concept however (besides naming convention) it's where you should put more logic. Business layer and Presentation Layer are what will change more often (and probably independently) but here you're directly calling business layer without any abstraction. How do you test your user interface without the attached business layer? What will happen when you need, for example, a
IsChanged property in
ECategoria? Will you add it in the shared class even if it's used only in presentation? Check MVC, MVP and MVVM to pick the one that best suits your needings (and your UI framework).
Also note that this line:
categoria.Idcategoria = Convert.ToInt32(this.txtcodigo.Text.Trim());
May fail (and trimming is optional here.) User input may be wrong and you must handle that, proof of concept:
if (Int32.TryParse(this.txtCodigo.Text, out categoryId))
categoria.CategoryId = categoryId;
; // Ooops input is not a number (formatted according to current culture)