I have legacy database.
I need to add nhibernate but for several columns in a table.
How can I make nhibernate not to complain that there are no properties for some columns.
In the future it is possible that new columns will be added, but they are not needed in my project.
How can I do this ?
Regards,
Darko
You shouldn't have any problems if those database columns are nullable, or if they have default values. When you think about it, the same is true when you are trying to do an SQL INSERT on a table.
Just map the columns that you need to properties of a class.
If you just need to read, do no map them;
Otherwise, if you need to write in them, you will need to map them (if they are not nullable or do not have default values), in order to provide the values needed by the database.
Related
I want to create new table with empty columns and specify the datatype later. Is it possible? I try to do so on myscompiler.io and it works. I don't know if it's just possible in such site or is it actually possible to create that once I use other tools to write my SQL.
No. The SQL syntax requires that a table be well-defined, with column names and data types. This is true in every database that I can think of.
You could possibly do what you want in one of three ways:
Your database might support some sort of generic type which you could use to define the column. For instance, SQL Server has a sql_variant type.
You could define the table with a specific type such as a string and change the type later using alter table.
You could define the table with a single primary key column and add columns as you decide what they are.
I don't recommend any of these approaches. Instead, I would suggest that you need to re-think how your application is structured. Tables represent entities and entities have properties. Generally when using databases, these things are known before you start doing any work. There may be some cases where dynamic table creation is useful, but that is definitely not the common approach when using databases.
Given a project I'm working on, we have an old database structure we're migrating data from into a new database structure, and we need to preserve the old keys for a few tables for backwards compatibility with some existing application functionality.
Currently, there are two approaches we are considering for addressing this need:
Create an extra nullable field for each table and insert the old key into that new field
Create companion table(s) that contain the old and new key mappings
Note: new data will not generate old ID keys, so in approach #1, eventually the nullable field will contain nulls over time for new records.
Which approach is better for a cleaner database design, and data management long-term?
Do you see any issues with either approach, and if so, what issues?
Is there a #3 approach that I haven't thought of yet?
You mention sql, but is it SQL-Server?
if SQL-Server, look into SET INSERT_IDENTITY. This allows you to explicitly insert values for the auto-increment columns vs being in a protected mode for that column.
However, I believe that if you explicitly include the PK in the insert statement with its value, it will respect that and save the original key in the original column you are hoping to retain without having to force yet another column for backward compatibility purposes.
I am trying to find a way to only populate a property of my entity class, if the column exists in the query?
When I execute a query using DbSet.SqlQuery and returning the column (which is an alias) populated, everything is fine. But when using the built in functionality such as All(), Find(), ToArray() etc, it expects that column to be in the dataset.
Is there a way (without having to write all of the supporting queries manually) to mark a property in my entity class, as optional.
It is currently marked as a nullable DateTime but the framework still complains it does not exist when using the built in functionality.
Any suggestions would be great!
Cheers
No, because they have to build the SQL query. It doesn't matter if a column is nullable or not, what matters is that when they build the query, if that column does not exist, then the database will likely throw an error complaining that the column does not exist.
The only way around it is to not map it, or to query the schema when mapping and conditionally map the property (though I wouldn't recommend that).
The user wants to add new fields in UI dynamically. This new field should get stored in database and they should be allowed to perform CRUD on it.
Now I can do this by specifying a XML but I wanted a better way where these new columns are searchable. Also the idea of firing ALTER statement and adding a new column seems wrong.
Can anyone help me with a design pattern on database server side of how to solve this problem?
This can be approached using a key value system. You create a table with the primary key column(s) of the table you want to annotate, a column for the name of the attribute, and a column for its value. When you user wants to add an attribute (say height) to the record of person 123 you add a row to the new table with the values (123, 'HEIGHT', '140.5').
In general you cast the values to TEXT for storage but if you know all the attributes will be numeric you can choose a different type for the value column. You can also (not recommended) use several different value columns depending on the type of the data.
This technique has the advantage that you don't need to modify the database structure to add new attributes and attributes are only stored for those records that have them. The disadvantage is that querying is not as straightforward as if the columns were all in the main data table.
There is no reason why a qualified business user should not be allowed to add a column to a table. It is less likely to cause a problem than just about anything else you can imagine including adding a new row to a table or changing. the value of a data element.
Using either of the methods described above do not avoid any risk; they are simply throwbacks to COBOL filler fields or unnecessary embellishments of the database function. The result can still be unnormalized and inaccurate.
These same business persons add columns to spreadsheets and tables to Word documents without DBAs getting in their way.
Of course, just adding the column is the smallest part of getting an information system to work, but it is often the case that it is perceived to be an almost insurmountable barrier. It is in fact 5 min worth of work assuming you know where to put it. Adding a column to the proper table with the proper datatype is easy to do, easy to use, and has the best chance of encouraging data quality.
Find out what the maximum number of user-added fields will be and add them before hand. For example 'User1', 'User2', 'User3', 'User4'...etc. You can then enable the fields on the UI based on some configurable settings.
Say I'm mapping a simple object to a table that contains duplicate records and I want to allow duplicates in my code. I don't need to update/insert/delete on this table, only display the records.
Is there a way that I can put a fake (generated) ID column in my mapping file to trick NHibernate into thinking the rows are unique? Creating a composite key won't work because there could be duplicates across all of the columns.
If this isn't possible, what is the best way to get around this issue?
Thanks!
Edit: Query seemed to be the way to go
The NHibernate mapping makes the assumption that you're going to want to save changes, hence the requirement for an ID of some kind.
If you're allowed to modify the table, you could add an identity column (SQL Server naming - your database may differ) to autogenerate unique Ids - existing code should be unaffected.
If you're allowed to add to the database, but not to the table, you could try defining a view that includes a RowNumber synthetic (calculated) column, and using that as the data source to load from. Depending on your database vendor (and the products handling of views and indexes) this may face some performance issues.
The other alternative, which I've not tried, would be to map your class to a SQL query instead of a table. IIRC, NHibernate supports having named SQL queries in the mapping file, and you can use those as the "data source" instead of a table or view.
If you're data is read only one simple way we found was to wrapper the query in a view and build the entity off the view, and add a newguid() column, result is something like
SELECT NEWGUID() as ID, * FROM TABLE
ID then becomes your uniquer primary key. As stated above this is only useful for read-only views. As the ID has no relevance after the query.