Generate Enums from Database or Vice Versa? - c#

I'm trying to figure out which is the the "correct" way to do this. I have a bunch of lookup tables in my database and would like to place an enum on top of those values so, when coding, it's easier to read (as well as not use hard-coded values).
I'm wondering if I should generate my table values based on an existing enumeration or if I should generate my enumeration from my table's values.
EDIT
Based on the first couple of comments, here are some clarifications:
Frequency of changes to the values could be rather frequent as they are intended to be rather dynamic. That being said, a compile will be necessary before adding any of these either way, because the enumeration needs to be updated to expose the new values.
The main reason for this need is because we don't want to tie people down to a specific list of values, we would like the applications to have the ability to add new entries as and when they need to.
In the past, we have generated the data from enumerations, but I'm second guessing myself

We usually generate enums from the database. We use CodeSmith, which allows us to create project files that can easily regenerate the enums as needed.
We've gone the other way occasionally, usually for reporting purposes (when existing enum values are persisted).
And, of course, we have enums whose values are never persisted.
In general the only reason to generate enums from the database is if code needs to make decisions based on them. If you just want to populate a ComboBox and persist the user's choice, don't generate an enum.
Obviously making decisions based on enums (or strings) whose values can change is fragile. You may want to consider including expiration dates (or "from" and "through" dates) in your database schema, so that existing values are not deleted. Filter expired values when populating UI selectors. This also makes it easier to have referential integrity.
As always in C#, you have to be aware that enum values may fall outside of the expected range. Include a default on your switch.
We came up with helper classes for creating cached lookup lists that make these easier to use.
I'm not advocating going down this route. If you have to, this is how we did it.

There's also a third option in that you have a explicit model which describes the schema in the level of detail you require and then you generate both data & schema from that model.
Regarding your question I think what you should do is thinking about the problem in your context and list pros/cons for you with each alternative and decide on what makes most sense for you and your business.
I have worked worked with all three strategies for different applications, the one I personally prefer is having an explicit model buts depending on the context.
Sorry for being fuzzy but I think for these kind of questions there's real golden rule which always applies in all cases.

Related

Exposing C# enums as views in database

Say if I have a column in database which can accept any one value of the enum that is defined in my C# code.
There is a usual way to make it be available to the database to store it in a database table and refer it from there.
But sometimes you don't want to store the enum in the database but just want to maintain it in the code, for these cases I have come up with the solution in my project to have a view which will return the values of enums so that we do not have to hard code it in the database, so having something like this in the database
CREATE VIEW ENUM.ValidationFailReasonTypes
AS
SELECT 1 AS [FormLevel], 2 AS [GridLevel]
For enum
public enum ValidationFailReasonTypes
{
FormLevel = 1,
GridLevel = 2
}
So just wanted to ask is it a good idea to do like this or is there some better way to handle this case when we don't want to store enum in the database?
It all depends.
Old school database folk like me want you to build validity checks into your data model. See this question for how you would do that. You end up with a nice, self-documenting schema, which guarantees that your application can only contain valid entries for ValidationFailReasonTypes.
An alternative view is that the database is just the storage mechanism, and it's perfectly OK for the application to be the guarantor of data validity, especially if it has lots of unit tests. In this case, you use an ENUM in you C#, write unit tests to validate that the entries match your expectations, and accept the fact your database table has an integer column which could contain lots of values, but the application limits it to (1, 2).
I think it's important to pick one approach and stick to it. Your solution - if I understand it correctly - is a bit of both.
In general, I'd use an enum for values that are not going to change without a new release of your application, usually because you're enabling some new functionality.
I'd expect to use a database entry for something that can change in the business domain independently of your application's release. "Grid level" and "form level" feel like features in your application, so I think an enum is okay.
The entire reason for an enum is consistency, clarity, and ease of use when coding. I would think you would want that sort of clarity and consistency on the database side as well. If you persist an enum value to the database, you absolutely should have referential integrity on the column and a corresponding definition table. The view saves you nothing in my opinion.
Create a table and add referential integrity to the field even if it only has two rows for all eternity.

When to use Enums with Entity Framework?

I've added enums to my C# Entity Framework 6, MVC 4 application. I like the approach as:
I think my model is clear that the value comes from a lookup.
I can easily bind them to a select list in my view using approached such as these: examples from Stack Overflow.
I'm not looking up the database to get the values.
I have less plumbing code to use the values.
On the downside, I'm thinking that:
I need to be careful to keep my database in sync with my code for actual lookup tables.
I guess, I would need to deploy the code every time I make a change to one, instead of perhaps having 'administration' tables where a user could add new lookup values. (I guess you could be selective and not use enums for values that would change a lot).
I'm just wondering what the real advantages of this approach are and if there are common scenarios when I would want to avoid it?
Thanks
I don't think your question is related to EF at all, it's more backend-agnostic.
The only real problem is what you have already suggested - having to recompile when you need to add/remove values. However, that all really depends on how often you actually expect the list to change.
The point of using an enum is for readability & simplicity from the developers perspective, however, if you enum is really just for UI purposes I'd argue that you could end up giving the developer more work in maintaining the list than doing a lot of work once and not having to worry about it again.
Having to re-compile just for the sake of adding a new option for a user seems very brittle to me.

Best practice : use enum or not to store dropdown values

I'm developping an application and I often ask myself the same question.
For example, I have many types of user and in a form used to create a user, there is a dropdown to specify which type of user.
The best way to populate this dropdown is to store values in a database's table ? If I do this, when I develop I want to test type of user and I have only an int. But I thing it's a better practice to test with enum. So I create enum but I feel it's a bad practice because I have to keep database and enum synchronized.
Another question is about localization. If I put values in database, I can't use resource file.
Could you tell me good pratices about this ?
Thanks
in your situation - the database would be the best practice here especially if its dynamic data. enum is for those values which are rarely to change, maybe once in a while but not on a frequent basis. you may have new entries entered in the database regularly especially for things like cascading drop down lists.
database certainly is the way to go in your situation. Enums are there for those times where they are just a set standard and rarely to change, for example:
Mr.
Miss.
Mrs.
Ms.
Dr.
you would have these in enums as they will never really change. on the other hands if store departments are to be changed or renamed, database would be the place to store such entries.
I strongly disagree with using enums for this kind of functionality, for basically two reasons:
Enumeration values have no behaviour, so compromise good OOP. A good class has data + behaviour, so enumeration members are not sufficiently specialised to represent the concept they are named for. The logic concerning this domain object lives somewhere else other than the entity that bears its name, which I dislike.
Enumerations are meant to convey ordinality, so DaysOfWeek is a good usage (except that which day of the week is 'first' varies depending on culture, but that' nitpicking) because the enumeration denotes the order of its members. In your case, does it make sense to say that a particular value is the 'first' user type, the second value is second, and so on? Probably not.
My first question would be - do you actually use the user type anywhere in the database?
If the answer is no, everything is easier, since you can simply use an enum and be done with it.
Otherwise, you probably should have a user type table as well, to get to use foreign keys properly.
Personally, I use manual ID for these - autogenerated keys can make a mess of your attempts to synchronize code and database. Ideally, if your ORM allows it, you could have the code-database synchronization automatic - either through code generation, or through automatic database data update. If you can't, though, manually coding the enums (or some kind of pseudo enum) should still be a lot nicer in the code.
As for localization, your options are completely the same. Just use a resource key like "UserType-XXX", where XXX is the database ID of the type. If you want, you can also store the localized values in the database. Just do whatever feels the best for your application.

Customizeable database

What would be the best database/technique to use if I'd like to create a database that can "add", "remove" and "edit" tables and columns?
I'd like it to be scaleable and fast.
Should I use one table and four columns for this (Id, Table, Column, Type, Value) - Is there any good articles about this. Or is there any other solutions?
Maybe three tables: One that holds the tables, one that holds the columns and one for the values?
Maybe someone already has created a db for this purpose?
My requirements is that I'm using .NET (I guess the database don't have to be on windows, but I would prefer that)
Since (in comments on the question) you are aware of the pitfalls of the "inner platform effect", it is also true that this is a very common requirement - in particular to store custom user-defined columns. And indeed, most teams have needed this. Having tried various approaches, the one which I have found most successful is to keep the extra data in-line with the record - in particular, this makes it simple to obtain the data without requiring extra steps like a second complex query on an external table, and it means that all the values share things like timestamp/rowversion for concurrency.
In particular, I've found a CustomValues column (for example text or binary; typically json / xml, but could be more exotic) a very effective way to work, acting as a property-bag for the additional data. And you don't have to parse it (or indeed, SELECT it) until you know you need the extra data.
All you then need is a way to tie named keys to expected types, but you need that metadata anyway.
I will, however, stress the importance of making the data portable; don't (for example) store any specific platform-bespoke serialization (for example, BinaryFormatter for .NET) - things like xml / json are fine.
Finally, your RDBMS may also work with this column; for example, SQL Server has the xml data type that allows you to run specific queries and other operations on xml data. You must make your own decision whether that is a help or a hindrance ;p
If you also need to add tables, I wonder if you are truly using the RDBMS as an RDBMS; at that point I would consider switching from an RDBMS to a document-database such as CouchDB or Raven DB

Need advice on combining ORM and SQL with legacy system

We are in the process of porting a legacy system to .NET, both to clean up architecture but also to take advantage of lots of new possibilities that just aren't easily done in the legacy system.
Note: When reading my post before submitting it I notice that I may have described things a bit too fast in places, ie. glossed over details. If there is anything that is unclear, leave a comment (not an answer) and I'll augment as much as possible
The legacy system uses a database, and 100% custom written SQL all over the place. This has lead to wide tables (ie. many columns), since code that needs data only retrieves what is necessary for the job.
As part of the port, we introduced an ORM layer which we can use, in addition to custom SQL. The ORM we chose is DevExpress XPO, and one of the features of this has also lead to some problems for us, namely that when we define a ORM class for, say, the Employee table, we have to add properties for all the columns, otherwise it won't retrieve them for us.
This also means that when we retrieve an Employee, we get all the columns, even if we only need a few.
One nice thing about having the ORM is that we can put some property-related logic into the same classes, without having to duplicate it all over the place. For instance, the simple expression to combine first, middle and last name into a "display name" can be put down there, as an example.
However, if we write SQL code somewhere, either in a DAL-like construct or, well, wherever, we need to duplicate this expression. This feels wrong and looks like a recipe for bugs and maintenance nightmare.
However, since we have two choices:
ORM, fetches everything, can have logic written once
SQL, fetches what we need, need to duplicate logic
Then we came up with an alternative. Since the ORM objects are code-generated from a dictionary, we decided to generate a set of dumb classes as well. These will have the same number of properties, but won't be tied to the ORM in the same manner. Additionally we added interfaces for all of the objects, also generated, and made both the ORM and the dum objects implement this interface.
This allowed us to move some of this logic out into extension methods tied to the interface. Since the dumb objects carry enough information for us to plug them into our SQL-classes and instead of getting a DataTable back, we can get a List back, with logic available, this looks to be working.
However, this has lead to another issue. If I want to write a piece of code that only displays or processes employees in the context that I need to know who they are (ie. their identifier in the system), as well as their name (first, middle and last), if I use this dumb object, I have no guarantee by the compiler that the code that calls me is really providing all this stuff.
One solution is for us to make the object know which properties have been assigned values, and an attempt to read an unassigned property crashes with an exception. This gives us an opportunity at runtime to catch contract breaches where code is not passing along enough information.
This also looks clunky to us.
So basically what I want advice on is if anyone else has been in, or are in, this situation and any tips or advice you can give.
We can not, at the present time, break up the tables. The legacy application will still have to exist for a number of years due to the size of the port, and the .NET code is not a in-3-years-release type of project but will be phased in in releases along the way. As such, both the legacy system and the .NET code need to work with the same tables.
We are also aware that this is not an ideal solution so please refrain from advice like "you shouldn't have done it like this". We are well aware of this :)
One thing we've looked into is to create an XML file, or similar, with "contracts". So we could put into this XML file something like this:
There is an Employee class with these 50 properties
Additionally, we have these 7 variations, for various parts of the program
Additionally, we have these 10 pieces of logic, that each require property X, Y and Z (X, Y and Z varies between those 10)
This could allow us to code-generate those 8 classes (full class + 7 smaller variations), and have the generator detect that for variation #3, property X, Y and K is present, and I can then tie in either the code for the logic or the interfaces the logic needs into this class automagically. This would allow us to have a number of different types of employee classes, with varying degrees of property coverage, and have the generator automatically add all logic that would be supported by this class to it.
My code could then say that I need an employee of type IEmployeeWithAddressAndPhoneNumbers.
This too looks clunky.
I would suggest that eventually a database refactoring (normalization) is probably in order. You could work on the refactoring and use views to provide the legacy application with an interface to the database consistent with what it expects. That is, for example, break the employe table down in to employee_info, employee_contact_info, employee_assignments, and then provide the legacy application with a view named employee that does a join across these three tables (or maybe a table-based function if the logic is more complex). This would potentially allow you to move ahead with a fully ORM-based solution which is what I would prefer and keep your legacy application happy. I would not proceed with a mixed solution of ORM/direct SQL, although you might be able to augment your ORM by having some entity classes which provide different views of the same data (say a join across a couple of tables for read-only display).
"We can not, at the present time, break up the tables. The legacy application will still have to exist for a number of years due to the size of the port, and the .NET code is not a in-3-years-release type of project but will be phased in in releases along the way. As such, both the legacy system and the .NET code need to work with the same tables."
Two words: materialized views.
You have several ways of "normalizing in place".
Materialized Views, a/k/a indexed views. This is a normalized clone of your source tables.
Explicit copying from old tables to new tables. "Ick" you say. However, consider that you'll be incrementally removing functionality from the old app. That means that you'll have some functionality in new, normalized tables, and the old tables can be gracefully ignored.
Explicit 2-way synch. This is hard, not not impossible. You normalize via copy from your legacy tables to correctly designed tables. You can -- as a temporary solution -- use Stored Procedures and Triggers to clone transactions into the legacy tables. You can then retire these kludges as your conversion proceeds.
You'll be happiest to do this in two absolutely distinct schemas. Since the old database probably doesn't have a well-designed schema, your new database will have one or more named schema so that you can maintain some version control over the definitions.
Although I haven't used this particular ORM, views can be useful in some cases in providing lighter-weight objects for display and reporting in these types of databases. According to their documentation they do support such a concept: XPView Concepts

Categories