Creating database views with NHibernate - database

Does any one know how to create a view from hibernate with the results of a criteria query?
We've got some legacy parts of our application that use views generated by the app for data retrieval and I like to tie the new NHibernate stuff into those for minimal friction.
I'd turn it into an extension method so I could eventually do stuff like this:
session.CreateCriteria<Thing>().CreateReportView().List();
Any ideas?
The existing process is like this:
SQLString = _bstr_t("SELECT name FROM User WHERE Retired = false");
...run the query process the results, then...
SQLStringView = _bstr_t(" \
BEGIN EXECUTE IMMEDIATE 'CREATE OR REPLACE VIEW ") + ViewName + _bstr_t(" AS ") + SQLString;
So whenever we run this query we get a view that has the same data in it. I can't work out how to replicate this is hibernate though.

To create a view using NHibernate directly, take a look at the 'database-object' mapping element.
Ayende has a good example here.

Check out this article for an explanation of mapping an entity class to a view and a table. I'm not certain that you'll be able to dynamically create your views at runtime as you specified; but perhaps this can be done as part of the schema generation process using the database-object mapping?

If you're only interested in filtering the data being returned, you may want to have a look at Nhibernate's filtering mechanisms; here is a good article outlining their usage.

Related

EF Core Views and SQL Parameters

I have created a view on SQL Server which produces a report for monthly totals. The view has been added to my DB Context and mapped successfully, therefore I am in a position where I can successfully get the results of my view as follows:
var list = db.MonthlyTotals.ToList();
However, I need to be able to restrict between dates and therefore needs to pass in some parameters for a start and end date.
Is this possible with either EF Core 6 or 7? Or do I need to use stored procedures instead?
I have created a view...I need to be able to restrict between dates and therefore needs to pass in some parameters for a start and end date...Is this possible with either EF Core 6 or 7?
Views don't use parameters, that's by design of the SQL Server Engine, and has nothing to do with whatever ORM you use, such as EF Core. If you really want to use parameters, then use stored procedures.
But the good news is, your use case is simple enough that you shouldn't need parameters anyway. Like Gert suggested in the comments, just use a Where clause against your view instead.
You can achieve this in C# with LINQ's method syntax like so:
var list = db.MonthlyTotals
.Where(mt => mt.YourDateColumn >= someDateVariable && my.YourDateColumn < someOtherDateVariable)
.ToList();
There's also query syntax with LINQ, which more closely resembles T-SQL code, but in my opinion is less intuitive in the context of C# as opposed to method syntax.

Multimapping in Dapper Without Custom SQL

Is there a way to use multimapping in Dapper in a generic way, without using custom SQL embedded in C# code?
See for example
Correct use of Multimapping in Dapper
Is there a generic way to query the data from 2 related entities, where common fields are determined automatically for join?
Don't do this. Don't even think this way! Databases are long lasting and normalized. Objects are perishable and frequently denormalized, and transitioning between the two is something to do thoughtfully, when you're writing your SQL. This is really not a step to automate. Long, painful experience has convinced many of us that database abstractions (tables and joins) should not just be sucked into (or generated out of) code. If you're not yet convinced, then use an established ORM.
If, on the other hand, you absolutely want to be in control of your SQL, but its the "embedding" in string literals in C# that bugs you, then I couldn't agree more. Can I suggest QueryFirst, a visual studio extension that generates the C# wrapper for your queries. Your SQL stays in a real SQL file, syntax validated, DB references checked, and at each save, QueryFirst generates a wrapper class with Execute() methods, and a POCO for the results.
By multi-mapping, I presume you want to fill a graph of nested objects. A nice way to do this is to use one QueryFirst .sql per class in your graph, then in the partial class of the parent, add a List of children. (QueryFirst generated POCOs are split across 2 partial classes, you control one of them, the tool generates the other.)
So, for a graph of Customers and their orders...
In the parent sql
select * from customers where name like #custName
The child sql
select * from orders where customerId = #customerId
In the parent partial class, for eager loading...
public List<Orders> orders;
public void OnLoad()
{
orders = new getOrders().Execute(customerId); // property of the parent POCO
}
or for lazy loading...
private List<Orders> _orders;
public List<Orders> orders
{
get
{
return _orders ?? _orders = new GetOrders().Execute(customerId);
}
}
5 lines of code, not counting brackets, and you have a nested graph, lazy loaded or eager loaded as you prefer, the interface discoverable in code (intellisense for the input parameter and result). Their might be hundreds of columns in those tables, whose names you will never need to re-type, and whose datatypes are going to flow transparently into your C#.
Clean separation of responsibilities. Total control. Disclaimer : I wrote QueryFirst :-)
Multimapping with Dapper is a method of running multiple SQL queries at once and then return each result mapped to a specific object.
In the context of this question, Multimapping is not even relevant, re: you're asking for a way to automatically generate a SQL query from the given objects and creating the correct joins which would result in a single SQL query which is not related to Multimapping.
I suspect what you're looking for is something along the lines of the Entity Framework. There are a couple of Dapper extension projects you may want to look into which will generate some of your SQL. See: Dapper.Rainbow VS Dapper.Contrib

Hibernate Entity Manager: Result Set Mapping

I'm new to Hibernate and I am a fan of iBATIS, but my new work environments forces me to use Hibernate. In the current scenario at my workplace, there are many complex select queries that I feel hibernate doesn't handles very well.
So I thought of writing my own native SQL select queries, with lots and lots of joins and conditions. So far so good.
I'm using the EntityManager to fire the queries and return the result set. The sample code will look like this:
String sqlQuery="select COL_1, COL_2 from MY_TABLE_NAME";
Query q=em.createNativeQuery(sqlQuery,);
List resultList=q.getResultList();
Please keep in mind this is just a code sample. I would like to have a way so that the result set as in this example (COL_1 and COL_2) can be mapped to my JAVA Class that has two (or more) fields.
Also note that this JAVA Class can not be an Entity that is linked to a table, So I need a way to define any of my JAVA class as a resultClass, the way we do in iBATIS.
Is there any way to do it? SO that the I just define a mapping somewhere for any JAVA class and the result set from query gets mapped to my JAVA Class automatically
String sqlQuery="select COL_1, COL_2 from MY_TABLE_NAME";
Query q=em.createNativeQuery(sqlQuery,MY_TABLE_NAME.class);
List<MY_TABLE_NAME> resultList=q.getResultList();
look variable in IDE debug mode, you will get what you want.

How to add data to db rows fetched with ZF?

I'm using Zend Framework's Zend_Db_Table classes to fetch data from a database.
I'd like to "refine" each row I fetch from a table by adding something to it. Within a plain old SQL query I would write eg. SELECT *, dueDate<NOW() AS isOverdue. In this example, feeding an extra field to the SQL query would be possible, but sometimes it might be more suitable to do the extra stuff with PHP. Anyway, I'd use this information mainly in my views, eg. to highlight overdue items accordingly.
What would be a good place to add this isOverdue data in a ZF application?
My thoughts so far:
finding that ZF has a built-in mechanism for this (not successful so far)
subclassing Zend_Db_Table_Row
overriding _fetch() in my Zend_Db_Table class
rethinking whether this is a sane pattern at all :)
As a bonus, it would be nice that I could still use ZF to update rows. Maybe this would be (another) reason for a naming convention for custom fields?
Why reinventing the wheel? There's a built in functionality to do this:
$this->select()->from('your_table_name_here', array('*', 'dueDate<NOW() AS isOverdue'));
Simply specify what columns you need using the second parameter of from() function and it will generate the SQL that you need (by default, if you do not use a second parameter it generates "SELECT * FROM table" query).
PavelDubinin.com - Professional Web Development blog

Is there any overhead with LINQ or the Entity Framework when getting large columns as part of an entity?

Let's say you have a table containing articles and you want want to display a list of them, excluding the actual article text. When you get a list of the article objects using LINQ or the Entity Framework, is there a LOT of overhead associated with getting that text column too? I assume that when you start enumerating the list, the article text will be stored in memory until the objects are disposed of.
So would it make sense to create an intermediary object that doesn't contain the text column? If so, how would you do this? Make a class inside your DAL, allow the ORM to automatically create one by setting up a stored procedure, or some other process?
The overhead isn't huge (just the cost of sending the data over the wire), but if you don't need the data sure, don't return it. I find the easiest way is to use anonymous types:
from a in Context.Articles
select new {Name = a.Name, Author = a.Author};
Since you're not actually materializing any Article instances, the Entity Framework won't need to fill out all the properties of an instance.
If you don't need the data you should definitely create a different type. By convention I typically name this sort of class "nnnInfo" or "nnnListItem". To create ArticleListItem, in L2S, simply drag the table to your DataContext designer a second time. Then rename it from 'Article1' to 'ArticleListItem' and remove the unneeded properties (rt click, delete). In EF, the process would be similar. As Craig notes, you could use anonymous types, but by creating a concrete type, you can reuse throughout your app, expose via services, etc.
A second way to do this would be to create the class manually and write an extension method to return ArticleListItem:
public static IQueryable<ArticleListItem> ToListItems(this IQueryable<Article> articles)
{
return from a in articles select new ArticleListItem{ Title = a.Title, ...}
}
This would allow you to "cast" any queries against Article as ArticleListItem...

Resources