Custom NHibernate entity persister for modifying generated SQL statements - sql

What I need is to populate entity from DB view (non-insertable) and make all entity updates to updatable DB table.
Mapping entity to table and writing custom load SQL from view is not an option since in some cases NHibernate still tries to select from table name (when joining this entity, for example).
Mapping entity to view and writing custom data modification queries is not an option since I can not write cross-database sql-insert statement (because of the last inserted identity value selection part).
The only idea I came up with for now is to modify generated SQL statements on-the-fly. I managed to do it with custom interceptor but I don't think that its a good idea (since I intercept every single query, even for other entities). However, I think that it should be possible to change only needed queries using custom IEntityPersister. I created one based on SingleTableEntityPersister, specified it in <class persister="…">, but NHibernate doesn't even want to instantiate it.
Are there any examples of writing custom entity persisters for NHibernate?

Related

How should I modify database model in Entity Framework?

EF beginner here.
How am I supposed to make changes in database model using Entity Framework?
I mean in DB model like changing datatypes of columns, adding attributes etc.?
E.g. I have string Password property in User table and I want to add [DataType(DataType.Password)] Attribute or [Required] or anything.
How am I supposed to do that? Of course along with applying changes to my DB? I created DB model from mdf local file (detached from mssql studio) using 'EF Designer from database' so I have my emdx model inside Models (asp.net mvc5) with classes for each table and DB MDF in App_Data.
Am I suppose to modify these classes?
Because I can add attributes right there but Diagram doesn't change and DB doesn't change. I guess I have to commit changes somehow.
I'll add that I can't enable migrations:
Creating a DbModelBuilder or writing the EDMX from a DbContext created using Database First or Model First is not supported.
EDMX can only be obtained from a Code First DbContext created without using an existing DbCompiledModel.
I think you are mixing allot of things here.
If you have an EDMX file, then your models are generated at compile time (or you can generate them from right click on the Model.tt file -> Run Custom Tool). So adding attributes to properties in a class representing a model entity will indeed be overwritten the next time you compile. The solution is:
Create another partial class to the generated classes
In the partial class, decorate the class with the [MetadataType] attribute and give it a type of a metadata class. The metadata class is a simple class, with the same properties as the generated class, but a different name, to prevent naming conflicts. From a design point of view, it should be abstract, because you're not supposed to create instances of it, but this is not required.
In the metadata class, decorate the matching properties with the validation and DataType attributes.
To the best of my knowledge, using model-first or database-first doesn't support migrations as in code-first. If you want to make changes to your schema (semi) automatically, I believe your best option is:
Make changes to your model in the EDMX designer
Right-click on the EDMX design surface -> Generate Database from Model.
After selecting the connection to your database, this will generate the SQL to generate your schema. This is a bit clunky, because it will erase your data each time, so you should have a script in place to re-populate your database after each time.

Is it possible to alter database using EntityFramework- Database First workflow

is it possible to change database tables (e.g adding a field in a particular table) in an application using Entity framework.??
My application used an existing database to generate a model nd entity classes out of that database, if now I want to change tables in my existing database , how can I do that using Entity framework, so that:
Changes are saved in previously generated Entity classes
Changes are saved in database also.
Well you'll either have to change the database or the model classes.. If you don't want to update both manually, you could just update the database DDL and then generate the Entity model again.

SQL views with Entity Framework

I have a SQL view to integrate with my application. I have been using Entity Framework till now. But the problem is that when I add a view to Entity Framework it starts treating my view as a table.
What I really want to know is, am I missing on something? Also if I use Nhibernate will this problem be resolved? Will it treat the view as a view only?
This view is a very complex query which has multiple joins and aggregation. That is why I am using a view.
But the problem is that when I add a view to Entity Framework it
starts treating my view as a table.
No it doesn't. If you add view to your model through wizard (EDMX designer) it will internally handle the view as a defining query which makes readonly entity. At entity level (the conceptual model) you don't see a difference because it is just another entity / class but if you try to make changes to instance of that class and save them you will get an exception (unless you map stored procedures or custom SQL commands to insert, update and delete operations for that entity).
Edit:
Database views as well as other database specific features like stored procedures or SQL functions are only for database first scenario (when you are using Update model from database in the designer).
Using Generate database from model is for Model first scenario where you tell VS: "Here is my model and I want some database to store it." First of all only information from conceptual model is used (original mapping and database description is replaced with a new one every time you run this command so even mapping to original database can be broken). It cannot create database specific features for you because it doesn't know that class should be mapped to view and moreover it doesn't know how should the view be created (the query from original view is unknown).
You can force VS to create the view for you but it is a lot of work in T4 templates where you will have to somehow provide SQL creation script for the view.

Nhibernate - Map a single row table

I have an existing nhibernate web application and I'm about to add a configuration table that will contain all system wide configuration options. This table will always contain one and only one row. Each column will contain one configuration property. I plan on having a domain object that will have a matching property for each column in the table. The users will be able to modify the values for each property in an admin screen. I plan on populating the table with one row during installation, setting initial values for each configuration option. My questions are as follows:
1) I only want the system to update the existing row, and want to block any deletes or inserts on the table. I can, of course, enforce this by not creating application tier functions that do deletes or updates, but I wondered if NHibernate had some built in mapping or configuration options to help. I'd prefer to not have to do this at the database level since we are writing a database agnostic application, and so far, have not had to write any database platform specific code or scripts.
2) Would the mapping be different for this class than my other "normal" classes?
Answer to 1) NHibernate does not have any "configuration" that will enable to block "inserts" and "deletes" only. You can do work arounds e.g. Write an your own PreDeleteEventListener and PreInsertEventListener and stop updates and inserts if the entity is your configuration entity.
However I would advise you do to enforce this configuration via the application i.e. the configuration repository should only expose an Update" function and no more.
Answer to 2) I am assuming that this table does not have a primary key (as it is the only row in the table). As far as Im aware, NHibernate cannot work with entities that do not have primary keys. You may have to add a primary key just to get it to work for NHibernate

S#arp Architecture / NHibernate with multiple databases

I'm using S#arp Architecture (which uses NHibernate). I have some entities mapped to tables in one database and others mapped to a different database. Disclosure: Databases already exist so i can't do model first.
How do I configure this to work?
EDIT: Would the SchemaIs method in Fluent NHibernate be the recommended approach to map an entity to a table in a different database? I believe this is possible via NHib's xmp mapping files too.
You should use NHibernateSession.AddConfiguration instead for additional database. The call to NHibernateSession.AddConfiguration goes immediately under NHibernateSession.Init(). An explicit session factory key will have to be defined for the second initialization.
The whole process is explained here in detail.
https://github.com/sharparchitecture/sharp-architecture/wiki?Page=FAQ
The way I have done this is to initialise multiple NHibernateSessions in InitializeNHibernateSession within global.asax.cs using multiple nhibernate config files. I then used [Transaction("nhibernate.dbname")] (dbname being names assigned to WebSessionStorages) in the controllers against each appropriate action method.