MVC3 NHibernate, SQL audit - nhibernate

I have some misunderstandings about the implementation of an SQL audit module, using as ORM Fluent NHibernate. So here is the situation:
We are talking about a Client-Server application build on MVC3 framework.
Suppose there we have a method which renders the grid:
[HttpGet]
public ActionResult ShowGrid()
{
var gridModel = _gridService.GetAllRecords();
return View(gridModel);
}
Now when somebody executes a DB Inser/Update/Delete command, I want that every client which views that grid to see that there are some changes inside.
I have 3 ideas:
1) To write a script that makes a refresh by calling the database, each X seconds. Making a full Select even if there are no changes yet. Worst decision
2) To create some sort of trigger, which updates a custom audit table, and then to check if there is some new data, by comparing some Object State/ LastUpdate fields. Better
3) To use some other tools (no have ideea what tools), that will offer some solutions.
If somebody have some information, maybe there already exists a solution please share. Thank you very much!

Using NHibernate, the easiest way:
NHibernate Interceptor
If you need implement something more complex you can mix it with event listeners:
Here
Or use:
NHibernate.Envers

Related

Entity Framework Core 1.0 - How to seed a large amount of data

I am using an ASP.NET Core 1.0 (previously known as ASP.NET 5) application with the core framework and Entity Framework Core 1.0 (previously known as Entity Framework 7).
In this blog https://blogs.msdn.microsoft.com/dotnet/2015/11/18/entity-framework-7-rc1-available the people in charge of development of EF Core 1.0 say that it is not recommended to use an ORM like entity for bulk inserting a large amount of data and they recommend a lower level approach such as SqlBulkCopy to do so using the database provider directly and skipping Entity Framework.
I have 120,000 records that I need to seed. At the moment I am using something like this:
private readonly MyDbContext _context;
public MyDbContextSeedData(MyDbContext context)
{
_context = context;
}
public void EnsureSeedData(string seedPortsFilePath)
{
SeedPorts(seedPortsFile);
}
private void SeedPorts(string seedPortsFilePath)
{
if (!_context.Ports.Any())
{
var ports = PortsData.GetPorts(seedPortsFile);
List<Port> listPorts = ports.ToList();
// the following statement commented out did not make any improvement
// _context.ChangeTracker.QueryTrackingBehavior = Microsoft.Data.Entity.QueryTrackingBehavior.NoTracking
_context.AddRange(portsRange);
_context.SaveChanges();
}
}
and I am calling the EnsureSeedData(path) from my Startup.cs where I have an instance of MyDbContextSeedData
My findings and questions with this approach:
It takes more than 30 minutes to insert all the records
I cannot use something like System.Data.SqlClient.SqlBulkCopy because this class does not exist in the core framework. Any alternative?
Entity Framework, behind the scenes and according to the logs, seems to be splitting the INSERT SQL statemens in chunks of 1999 values. It also seems to close the DB connection between insertions. I guess this is all managed in the most efficient way by Entity anyway..
I could not find any example on the best practices to seed a database. Should I use something similar to my approach and seed from the code when the application starts (assuming I find a quicker way to do the inserts)? Or should I use some kind of Migration that executes a SQL script?
Any example on how to seed large amounts of data using ASP.NET Core framework dnxcore50 would be appreciated!
I believe you are mistaken about System.Data.SqlClient.SqlBulkCopy:
https://github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient/src/System/Data/SqlClient/SqlBulkCopy.cs
Do as they recommend, ditch entity framework (of whatever stripe) and use sql bulk copy if this is going to be an on going task. On the other hand, you say "seed" -- if this is a one time thing, just do it straight in the database, and then restore from backup for future "start from scratch" situations.

How to access context after each Entity Framework db migration

When I Add-Migration, I get the appropriate DbMigration class with the Up / Down methods, where I am able to make schema changes and (with the use of the Sql() method) can make data/content changes as well.
I'd like to be able to make content changes per migration using the database context. I understand that I could use the Seed method in a Configuration class, but my understanding is that I can only wire up one Configuration with my initializer.
I'd prefer to have a UpCompleted()/DownCompleted() methods that would provide access to the db context after the migration completed. This would enable writing incremental data/context change "scripts" in a manner that would be less prone to errors than using the Sql() method.
Am I missing something? Is this possible?
Thanks!
That doesn't really work because the context only has your most recent model - which can only be used to access the database once the most recent migration has run (which is effectively what Seed achieves).
For an example of how this idea breaks, if you moved a property from one class to another then seed logic from older migrations would no longer compile. But you couldn't change it to use the new property because the corresponding column wouldn't exist in the database yet.
If you want to write this kind of seed/data-manipulation logic, you need to put it at the end of the Up/Down methods and use the Sql method to perform it using raw SQL.
~Rowan

How do I add Retry Logic in NHibernate to handle Transient Failures in SQL Azure?

We have a .NET application that runs on Windows Azure and uses NHibernate to connect to a SQL Azure database. Sometimes it's necessary to add retry logic to handle transient failures in SQL Azure as described for example here -
http://social.technet.microsoft.com/wiki/contents/articles/retry-logic-for-transient-failures-in-sql-azure.aspx
Can someone point me to a way in doing this with NHibernate? Ideally I'd like to do this at the NHibernate level and not wrap every single call; I was able to do this for another ORM, .netTiers (http://nettiers.com) as I outline here -
http://blog.ehuna.org/2010/01/how_to_stop_getting_exceptions.html
I did search and found some answers that mention using a custom implementation of the IDbCommand interface -
Intercept SQL statements containing parameter values generated by NHibernate
But I'm not sure this works with NHibernate 3.2 and I'm looking for a clear example I could modify.
How could I make NHibernate retry calls to SQL Azure automatically? Let's say 3 retries, with 100ms wait between each - after the 3 retries, if still failing, we should throw the exception.
I've released a library that takes care of this:
https://github.com/robdmoore/NHibernate.SqlAzure
This is not a complete running example, but the files you need are here
https://github.com/craigvn/NHibernateRetryable
Maybe this can help you out:
http://www.objectreference.net/post/NHibernate-and-Execution-Plans.aspx. Here there is a class that you can download and play with it, with some overrides.
Also check this link as well: http://elliottjorgensen.com/nhibernate-api-ref/NHibernate.Driver/SqlClientDriver.html
I hope it helps in anyway, I'm going thru a similar situation.
Regards,

What is the fastest way to clear out a database using NHibernate?

I intend to perform some automated integration tests. This requires the db to be put back into a 'clean state'. Is this the fastest/best way to do this?
var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly("Bla");
new SchemaExport(cfg).Execute(false, true, false);
var se = new SchemaExport(conf);
se.Drop(false, true);
se.Create(false, true);
Yes it almost is. You don't have to create a new configuration object before each test, you can reuse it when created once. You can make it faster by using an inmemory database like sql-lite for testing.
My integration tests do SessionFactory creation in a base class constructor, and SchemaExport in test fixture setup. I also test against SQLite running as an in-memory database for extra speed.
Ayende gave a good example of this approach in this blog post. Tobin Harris' article includes timing data of drop/create vs delete.
Me I use Proteus, it's an open source library. Before each test, there is an auto save of your set of data , load the set you want to test (an empty DB for exemple). After each test, the set of data is reloaded after the last test, the data present in the database before the tests are restored.
Since NHibernate is database independent another interesting option if you are having it generate your database is to run your tests against something like SQLite which is in memory. Things will run MUCH faster that way.
Here is an article on showing how to do this with ActiveRecord but you can take the concept and use it without ActiveRecord.
And here is a discussion if you're having trouble getting it working (I did at first).

Synchronizing NHibernate Session with database - the reverse way

I am using NHibernate for a project, and I am absolutely beginner. I am fetching some objects from a table and showing it to a form, where they can be edited. If an user inserts a new object into the table from some other window, I want to show this newly inserted object into the edit window. My application uses tabbed window interface, so user can simultaneously open insert window and edit window at the same time.
So basically what I need is a way to determine if a newly created object exists in the database which is not fetched before by ISession, and if not, then fetch that new object from the database. In other words, I need to synchronize my session with the database, just like flush method, but in the reverse way.
Can anyone help me?
Publish/Subscription method works well for this. Check out the Publishing Events part of Ayende's sample desktop application. Basically after you've added a new item, you publish that information and other parts of your application that subscribed can update their lists accordingly.
You are taking the path to NHibernate Hell.
Be sure to work your infrastructure (ie defining interfaces, defining session management patterns and notification pattern) and isolate these non-business utilies from the rest of your code before using NHibernate to implement them.
Good luck.