Repository Pattern Contestation - linq

According to Martin Fowler:
... "Client objects construct query
specifications declaratively and
submit them to Repository for
satisfaction" ...
Why? What are the advantages at that point?
I see one disadvantage: database queries are spread and hidden over ties. That makes it harder to debug.

The advantage is that the "what" (the declarative specification) is separated from the "how" or implemenation details. So the client doesn't need to know whether it's querying a relational database, a Web service, an object database (eg Mongo), an XML data store, etc.
Let's assume you're using an RDBMS. Even so, the client is isolated from needing to know whether the database is Oracle, MS SQL, SQLite, mySQL, PostGres, etc. This will save you a lot of headache when the commandment "thou shalt (not) use MS SQL" (or whatever) comes down from the mountain.
The additional layer does introduce some overhead. But (1) ORM tools like (N)Hibernate are quite good at optimizing the generated queries for whatever back-end you're using, and (2) the overhead is generally negligible compared to the cost of database read, let alone a web service call.
We're converting from LINQ to NHibernate right now to avoid the "N+1" problem (ie you generate one query/hit for each "master" database record, plus a query/hit for each "child" record).
And BTW ... there is such a thing as LINQ to NHibernate.

Related

HANA CDS Views vs Calculation Views vs Table Functions

In SAP HANA I am used to create Calculation Views.
Previously I learned that Calculation Views (which after compilation are column-views) are to be prefered over Database-SQL-Views.
Now with CDS-Views I am not sure if this is still the case. Especially with regards to performance.
Also what is now the difference between a table function (which replaced scripted calculation views) and CDS Views?
Ok, this is a question that I believe requires some background to be answered.
A long, long time ago...
When SAP HANA was first developed, it heavily reused concepts and technology from other, already existing SAP products (TREX, P*TIME, MaxDB, Business Warehouse Accelerator).
One of the fundamental elements of the high query performance was (and is) the column store data-storage, which came in large parts from the TREX/BWA products. These products, in turn, had been solutions to very specific problems (full-text search for catalogs and speed-up of analytical queries from the SAP Business Warehouse data warehouse product).
Especially the BWA use case reflects in the column views of SAP HANA. Due to the limited use case of supporting SAP BW queries, no general SQL/relational query support was required (e.g. no arbitrary join-chain optimizations, no SQL features beyond SQL:92 etc.) whereas other, rather exotic features (like "vertical join") that could be used by SAP BW, were built into a query tool/engine ("engine" clearly was a very popular term with the SAP developers).
Once HANA proved successful as a platform to run SAP BW on, the next step was to add flexibility and make more general platforms like SAP Netweaver (the software that SAP's business solution products run on/with) working on SAP HANA. Now, SQL features were added and those required additional capabilities from the query optimizer and execution "engines".
Query optimization had to be flexible and fast and should lead to query performance that would still beat the existing RDBMS vendors' offering (which had been around for 40+ years).
This, clearly, is a hard problem and throwing is operational aspects of DB development (scaling, solution deployment, data federation, etc.).
This led to an overlapping development of different tools addressing different aspects of DB development.
SQL support and the underlying SQL optimizer were made more powerful, so much so, that (some) SQL queries could be as fast or faster than those modeled in calculation views. And since both of these "query frontends" eventually had to talk to the same internal data structures (row/column store) it was desirable to have just a single query optimizer, that would support all the different use cases.
Somewhere around HANA 1 SPS11/12 most calculation views started to be "unrolled" internally to feed into the common optimizer (that was what the "Execute in SQL Engine" flag was about).
I'd say, since then, the performance argument for using calculation views only holds in very specific circumstances.
I mentioned the overlapping developments and CDS (core data services) is one of them. The idea here is a very different one from SQL. While SQL gives you "the way to talk to the database", CDS wants to give your application a single data definition, that is used by the UI, the program logic and the data storage/query execution.
SQL != CDS
This probably needs some context (again): a major usage pattern of how SQL databases are used by application developers is that the application is written in some form of OO-implementation and the talking to the DB is left to a mapping layer/library (e.g. O/R-mappers). This means, that the knowledge of what the application is about (aka business process knowledge), is spread out in the application.
There is some information about it in the UI (labels, formatting, visibility, ...), some of it is in the application-object model (object dependencies, hierarchies, value domains...) and then some of it is in the queries against the database.
Such scattered knowledge/definition makes it hard to make changes consistent, which in turn, slows the development process and in turn prolongs the time until the application can run and deliver some positive outcome.
"Time-to-value" is the thing under optimization here as this is important for companies that give the promise of "success through innovation".
Ok, so this CDS thing is now part of the development models proposed by SAP and nearly en-passant also addresses topics like schema evolution and deployment of the data model. It is, in fact, independent of the actual database platform as shown in the CDS for ABAP variety.
How does this lead back to query performance? It does not really.
CDS' advantage is that one can provide more information about the data model than what is possible in HANA SQL.
Associations and joins with cardinality declaration (albeit now retrofitted to plain SQL) can enable the optimizer to use additional optimizations. Yet, the same optimizer and the same query execution "engines" are used here.
So, from a (query execution) performance point of view, it does not make a big difference, as long as no query semantics are required for which CDS does not have syntax (e.g. some window functions).
The main point of CDS really is about application development process performance and whether that works well with how you do development really depends on how much of it you can use.
Now for the question "scripted calc view" vs. "table function" vs. "CDS view".
Looking at these different object types from the point of "what can I do with them functionally?" will result in the observation "basically, the same".
The difference lies in how these can be optimized (scripted calc views cannot be generally unrolled into the global query to be optimized), and what one can do with the object once created.
Table functions allow for very easy reuse across multiple views and queries. They also provide the option to provide parameters into the function (similar to parameterized views) and in addition allow for imperative coding.
Functionally speaking, table functions are a kind of swiss-army knife; one can do nearly anything with them and they still can be part of global query optimization.
CDS views, as mentioned above, are nothing "special" in terms of query runtime or optimization. The main reason why CDS views are "a thing" is that with HANA SAP started to develop development models (such as XS, XSA, CAM) that revolve around "virtual data models".
The idea for those is that the structure of tables very often is stable and changes only little over time.
In a way, this is the "write-schema" of applications that enter the data into tables.
The "read-schema" is most of the time different from that. Queries re-combine the normalized data into records that the application can map into objects. This allows applications to look at the data differently than the original application.
With "virtual data models" these queries are baked into tangible development artifacts (the views) that can be reused across the application. In fact, these can be treated as if this was the database with its tables, presented in a way that makes sense for the application.
Once again, if that is something that is beneficial for your application development depends on how your application development looks like.
Can you use HANA without CDS? Absolutely, and there are many areas where CDS lacks (i.e. the limited syntax and feature mapping to HANA features) but it does have its merits.
Should you abandon calculation views?
I would not necessarily change existing developments if they still serve their purpose, but calculation views certainly are an odd development object. Training folks in using those and SQL most likely is overly expensive compared to just sticking to SQL.
Personally, I prefer the code-based SQL development (better tooling available, allows for easier comparison with other DBMS, doesn't require WEB IDE/HANA Studio).
The only thing, SQL based development does not provide is the extended annotations/semantic information used by the SAP analytic frontend tools (SAC & BO) - these really are specific to CDS and Information Models (calculation views) but barely used by other analytic tools.
And that's my take on it.
I would add that
Calculation Views are semantically richer. A SQL View does not know about measures, dimensions, hierarchies. https://blogs.sap.com/2019/08/26/what-is-the-difference-calcview-versus-sql-view/
The difference from the execution plan point of view is getting less and less. In Hana 2.0 SP4 most graphical calc views are turned internally into a single SQL statement to be executed by the SQL engine. So in that sense, using a CalcView gives you the additional information about the model plus the query performance of the SQL engine.
Lars' explanation of CDS is perfect. Nothing to add there.
But Imagine the situation when you can't create a table function because of limited license (aka runtime version). Just stay with scripted views.
The main advantage of Hana artifacts over CDS at present is the ability to use input parameters in complex cases to optimize resources and query performance - when your logic is pushed down into DB instead of AS / app. But many native SQL features are still not available in graphical views (for example - exists, JOIN on BETWEEN), so I think that 10 years later HANA artifacts will become "very rare".
So learn CDS syntax :)
Always a glad experience reading an article or pov from Lars, on any media (StackOverflow, SAP blog, article, twitter).
I just want to point out that another thing that I miss from the SQL scripting (SP, TF, SF) is the join optimization and SQL propagation that Information View has.
This is for me the focus to flexible models (apart from dynamic join that is only relevant for certain scenarios), to deliver one view that will perform depending on which columns the user or app will request.
For the semantics use, I can simply expose a TF inside an information view to add some.
You can tell me that CDS have both options available (join optimization, SQL propagation, and annotation) but for advanced or complicated scenarios (window functions not present at CDS), and also for non-SAP developers, it will be more simple and the go-to approach for beginners

rewriting a SQL/vb6 app - should I use nHibernate or Linq

I have a legacy VB6 app which I am rewriting in .Net. I have not used an ORM package before (being the old fashioned type who likes to know what SQL is being used), but I have seen good reports of NNibernate and I am tempted to use it for this project. I just want to check I won't be shooting myself in the foot.
Because my new app will initially run alongside the existing one, any ORM I use must work with the existing database schema. Also, I need to use SQL server text searching. From what I gather, LINQ to SQL does not support Text searching, so this will rule it out.
The app uses it's own method of allocating IDs for new objects - will NHibernate allow this or does it expect to use it's own mechanisms?
Also I have read that NHibernate does caching. I need to make sure that rows inserted outside of NHibernate are immediately accessible when accessing the database from NHibernate and vice versa.
There are 4 or 5 main tables and 10 or so subsidiary tables. although a couple of the main tables have up to a million rows, the app itself will normally be only returning a few. The user load is low so I don't anticipate performance being a problem.
At the moment I'm not sure whether it will be ASP.NET or win forms but either way I will be expecting to use data binding.
In terms of functionality, The app is not particulatly complicated - the budget to re-implement it is about 20 man days, so if I am going to use ORM it has to be something that will start paying for itself pretty quickly. Similarly I want the app to be simple to deploy and not require some monster enterprise framework.
Any thoughts on whether this is a suitable project for NHibernate would be much appreciated.
While ORMs are good, I personally wouldn't take on the risk of trying to use any ORM on a 20 day project if I had to absorb the ORM learning curve as I went.
If you have ADO.NET infrastructure you are comfortable with and you can live without ORM features, that is the much less risky approach to take.
You should learn ORMs and Linq (not necessarily Linq To Sql) eventually, but it's much more enjoyable when there is no immediate time pressure.
This sounds more like a risk management issue and that requires you to make a personal decision about how willing you are to see the project fail due to embracing new (to you) technologies.
You might also check out LLBL Gen Pro. It is a very mature ORM that handles a lot of different scenarios.
I have successfully fitted an NHibernate domain model to a few legacy database schemas - it's not yet proved impossible, but it is sometimes not without its difficulties. The easiest schemas to map are those where all primary keys and foreign keys are single column ones, but with so few tables you should be able to do the mapping relatively quickly even if this is not true of yours.
I strongly recommend, particularly given your timescale, that you use Fluent NHibernate to do your mappings - the time to learn the XML mapping file syntax may be too big an ask. However, you will need to use an XML mapping file for your full-text indexing stuff (assuming that's what you meant), writing these as named SQL queries. (See nhibernate.info documentation for details.)
Suggest you spend a day or two trying to create a model for a couple of your tables, and writing code to interact with them. There'll always be people on SO ready to answer any questions you have.
You may also want to take a look at Linq to NHibernate - we've found it helpful in terms of abstracting even more of our database access stuff away behind a simple interface. But it's Fluent NHibernate that will give you the biggest and quickest win in terms of "cheating" on the NHibernate learning curve.

What are the advantages of LINQ to SQL?

I've just started using LINQ to SQL on a mid-sized project, and would like to increase my understanding of what advantages L2S offers.
One disadvantage I see is that it adds another layer of code, and my understanding is that it has slower performance than using stored procedures and ADO.Net. It also seems that debugging could be a challenge, especially for more complex queries, and that these might end up being moved to a stored proc anyway.
I've always wanted a way to write queries in a better development environment, are L2S queries the solution I've been looking for? Or have we just created another layer on top of SQL, and now have twice as much to worry about?
Advantages L2S offers:
No magic strings, like you have in SQL queries
Intellisense
Compile check when database changes
Faster development
Unit of work pattern (context)
Auto-generated domain objects that are usable small projects
Lazy loading.
Learning to write linq queries/lambdas is a must learn for .NET developers.
Regarding performance:
Most likely the performance is not going to be a problem in most solutions. To pre-optimize is an anti-pattern. If you later see that some areas of the application are to slow, you can analyze these parts, and in some cases even swap some linq queries with stored procedures or ADO.NET.
In many cases the lazy loading feature can speed up performance, or at least simplify the code a lot.
Regarding debuging:
In my opinion debuging Linq2Sql is much easier than both stored procedures and ADO.NET. I recommend that you take a look at Linq2Sql Debug Visualizer, which enables you to see the query, and even trigger an execute to see the result when debugging.
You can also configure the context to write all sql queries to the console window, more information here
Regarding another layer:
Linq2Sql can be seen as another layer, but it is a purely data access layer. Stored procedures is also another layer of code, and I have seen many cases where part of the business logic has been implemented into stored procedures. This is much worse in my opinion because you are then splitting the business layer into two places, and it will be harder for developers to get a clear view of the business domain.
Just a few quick thoughts.
LINQ in general
Query in-memory collections and out-of-process data stores with the same syntax and operators
A declarative style works very well for queries - it's easier to both read and write in very many cases
Neat language integration allows new providers (both in and out of process) to be written and take advantage of the same query expression syntax
LINQ to SQL (or other database LINQ)
Writing queries where you need them rather than as stored procs makes development a lot faster: there are far fewer steps involved just to get the data you want
Far fewer strings (stored procs, parameter names or just plain SQL) involved where typos can be irritating; the other side of this coin is that you get Intellisense for your query
Unless you're going to work with the "raw" data from ADO.NET, you're going to have an object model somewhere anyway. Why not let LINQ to SQL handle it for you? I rather like being able to just do a query and get back the objects, ready to use.
I'd expect the performance to be fine - and where it isn't, you can tune it yourself or fall back to straight SQL. Using an ORM certainly doesn't remove the need for creating the right indexes etc, and you should usually check the SQL being generated for non-trivial queries.
It's not a panacea by any means, but I vastly prefer it to either making SQL queries directly or using stored procs.
I must say they are what you have been looking for. It takes some time getting used to it, but once you do you can't think of going back (at least for me).
Regarding linq vs. stored procedures, you can have poor performance on either if you build it wrong. I moved to linq to sql some stored procedures of a client that were awfully coded, so the time dropped from 20secs (totally unaceptable for a web app) to < 1 sec. And much much less code then the stored procedure solution.
Update 1: Also you get a lot of flexibility, as you can limit the columns of what you are getting and it will actually only retrieve that. On the stored procedure solution you have to define a procedure for each column set you are getting, even if the underlying queries are the same.
Just as an update, here are some links on the future of LINQ to SQL:
What is the Future of Linq to SQL
Has Microsoft confirmed their stance on LINQ to SQL end-of-life?
Is LINQ to SQL Dead or Alive?
As a comment in the last link states, LINQ to SQL isn't going to go away, just not "improved upon" at least by Microsoft. Take these comments and posts as you will, just be cautious in your development plans.
We switched over to LINQ2Entity over the Entity Framework environment recently. Before, we had basic SQLadapters. Since the database we are working with is rather small, I cannot comment on the performance of LINQ.
I must admit though, writing queries have become a lot easier, and the addition of Entities, does enable strong typing.

Is Hibernate good for batch processing? What about memory usage?

I have a daily batch process that involves selecting out a large number of records and formatting up a file to send to an external system. I also need to mark these records as sent so they are not transmitted again tomorrow.
In my naive JDBC way, I would prepare and execute a statement and then begin to loop through the recordset. As I only go forwards through the recordset there is no need for my application server to hold the whole result set in memory at one time. Groups of records can be feed across from the database server.
Now, lets say I'm using hibernate. Won't I endup with a bunch of objects representing the whole result set in memory at once?
Hibernate does also iterate over the result set so only one row is kept in memory. This is the default. If it to load greedily, you must tell it so.
Reasons to use Hibernate:
"Someone" was "creative" with the column names (PRXFC0315.XXFZZCC12)
The DB design is still in flux and/or you want one place where column names are mapped to Java.
You're using Hibernate anyway
You have complex queries and you're not fluent in SQL
Reasons not to use Hibernate:
The rest of your app is pure JDBC
You don't need any of the power of Hibernate
You have complex queries and you're fluent in SQL
You need a specific feature of your DB to make the SQL perform
Hibernate offers some possibilities to keep the session small.
You can use Query.scroll(), Criteria.scroll() for JDBC-like scrolling. You can use Session.evict(Object entity) to remove entities from the session. You can use a StatelessSession to suppress dirty-checking. And there are some more performance optimizations, see the Hibernate documentation.
Hibernate as any ORM framework is intended for developing and maintaining systems based on object oriented programming principal. But most of the databases are relational and not object oriented, so in any case ORM is always a trade off between convenient OOP programming and optimized/most effective DB access.
I wouldn't use ORM for specific isolated tasks, but rather as an overall architectural choice for application persistence layer.
In my opinion I would NOT use Hibernate, since it makes your application a whole lot bigger and less maintainable and you do not really have a chance of optimizing the generated sql-scripts in a quick way.
Furthermore you could use all the SQL functionality the JDBC-bridge supports and are not limited to the hibernate functionality. Another thing is that you have the limitations too that come along with each layer of legacy code.
But in the end it is a philosophical question and you should do it the way it fits you're way of thinking best.
If there are possible performance issues then stick with the JDBC code.
There are a number of well known pure SQL optimisations which
which would be very difficult to do in Hibernate.
Only select the columns you use! (No "select *" stuff ).
Keep the SQl as simple as possible. e.g. Dont include small reference tables like currency codes in the join. Instead load the currency table into memory and resolve currency descriptions with a program lookup.
Depending on the DBMS minor re-ordering of the SQL where predicates can have a major effect on performance.
If you are updateing/inserting only commit every 100 to 1000 updates. i.e. Do not commit every unit of work but keep some counter so you commit less often.
Take advantage of the aggregate functions of your database. If you want totals by DEPT code then do it in the SQL with " SUM(amount) ... GROUP BY DEPT ".

NHibernate vs LINQ to SQL

As someone who hasn't used either technology on real-world projects I wonder if anyone knows how these two complement each other and how much their functionalities overlap?
LINQ to SQL forces you to use the table-per-class pattern. The benefits of using this pattern are that it's quick and easy to implement and it takes very little effort to get your domain running based on an existing database structure. For simple applications, this is perfectly acceptable (and oftentimes even preferable), but for more complex applications devs will often suggest using a domain driven design pattern instead (which is what NHibernate facilitates).
The problem with the table-per-class pattern is that your database structure has a direct influence over your domain design. For instance, let's say you have a Customers table with the following columns to hold a customer's primary address information:
StreetAddress
City
State
Zip
Now, let's say you want to add columns for the customer's mailing address as well so you add in the following columns to the Customers table:
MailingStreetAddress
MailingCity
MailingState
MailingZip
Using LINQ to SQL, the Customer object in your domain would now have properties for each of these eight columns. But if you were following a domain driven design pattern, you would probably have created an Address class and had your Customer class hold two Address properties, one for the mailing address and one for their current address.
That's a simple example, but it demonstrates how the table-per-class pattern can lead to a somewhat smelly domain. In the end, it's up to you. Again, for simple apps that just need basic CRUD (create, read, update, delete) functionality, LINQ to SQL is ideal because of simplicity. But personally I like using NHibernate because it facilitates a cleaner domain.
Edit: #lomaxx - Yes, the example I used was simplistic and could have been optimized to work well with LINQ to SQL. I wanted to keep it as basic as possible to drive home the point. The point remains though that there are several scenarios where having your database structure determine your domain structure would be a bad idea, or at least lead to suboptimal OO design.
Two points that have been missed so far:
LINQ to SQL does not work with Oracle
or any database apart from SqlServer. However 3rd parties do offer better support for Oracle, e.g. devArt's dotConnect, DbLinq, Mindscape's LightSpeed and ALinq. (I do not have any personal experience with these)
Linq to NHibernate lets you used
Linq with a Nhiberate, so it may
remove a reason not to use.
Also the new fluent interface to Nhibernate seems to make it less painful to configure Nhibernate’s mapping. (Removing one of the pain points of Nhibernate)
Update
Linq to Nhiberate is better in Nhiberate v3 that is now in alpha. Looks like Nhiberate v3 may ship towards the end of this year.
The Entity Frame Work as of .net 4 is also starting to look like a real option.
#Kevin: I think the problem with the example you are presenting is that you are using a poor database design. I would have thought you'd create a customer table and an address table and normalized the tables. If you do that you can definately use Linq To SQL for the scenario you're suggesting. Scott Guthrie has a great series of posts on using Linq To SQL which I would strongly suggest you check out.
I don't think you could say Linq and NHibernate complement each other as that would imply that they could be used together, and whilst this is possible, you're much better off choosing one and sticking to it.
NHibernate allows you to map your database tables to your domain objects in a highly flexible way. It also allows you to use HBL to query the database.
Linq to SQL also allows you to map your domain objects to the database however it use the Linq query syntax to query the database
The main difference here is that the Linq query syntax is checked at compile time by the compiler to ensure your queries are valid.
Some things to be aware of with linq is that it's only available in .net 3.x and is only supported in VS2008. NHibernate is available in 2.0 and 3.x as well as VS2005.
Some things to be aware of with NHibernate is that it does not generate your domain objects, nor does it generate the mapping files. You need to do this manually. Linq can
do this automatically for you.
Fluent NHibernate can generate your mapping files based on simple conventions. No XML-writing and strongly typed.
I've recently worked on a project, where we needed to change from Linq To SQL to NHibernate for performance reasons. Especially L2S's way of materializing the objects seems slower than NHibernate's ditto and the change management is quite slow too. And it can be hard to turn the change management off for specific scenarios where it is not needed.
If you are going to use your entities disconnected from the DataContext - in WCF scenarios for example - you're may have a lot of trouble connecting them to the DataContext again for updating the changes. I have had no problems with that with NHibernate.
The thing I will miss from L2S is mostly the code generation that keeps relations up-to-date on both ends of the entities. But I guess there are some tools for NHibernate to do that out there too...
Can you clarify what you mean by "LINQ"?
LINQ isn't an data access technology, it's just a language feature which supports querying as a native construct. It can query any object model which supports specific interfaces (e.g. IQueryable).
Many people refer to LINQ To SQL as LINQ, but that's not at all correct. Microsoft has just released LINQ To Entities with .NET 3.5 SP1. Additionally, NHibernate has a LINQ interface, so you could use LINQ and NHibernate to get at your data.
By LINQ, I'm assuming you mean LINQ to SQL because LINQ, by itself, has no database "goings on" associated with it. It's just an query language that has a boat-load of syntac sugar to make it look SQL-ish.
In the very basic of basic examples, NHibernate and LINQ to SQL seem to both be solving the same problem. Once you get pass that you soon realize that NHibernate has support for a lot of features that allow you to create truly rich domain models. There is also a LINQ to NHibernate project that allows you to use LINQ to query NHibernate in much the same way as you would use LINQ to SQL.
First let´s separate two different things:
Database modeling is concerned about the data while object modeling is concerned about entities and relationships.
Linq-to-SQL advantage is to quickly generate classes out of database schema so that they can be used as active record objects (see active record design pattern definition).
NHibernate advantage is to allow flexibility between your object modeling and database modeling. Database can be modeled to best reflect your data taking in consideration performance for instance. While your object modeling will best reflect the elements of the business rule using an approach such as Domain-Driven-Design. (see Kevin Pang comment)
With legacy databases with poor modeling and/or naming conventions then Linq-to-SQL will reflect this unwanted structures and names to your classes. However NHibernate can hide this mess with data mappers.
In greenfield projects where databases have good naming and low complexity, Linq-to-SQL can be good choice.
However you can use Fluent NHibernate with auto-mappings for this same purpose with mapping as convention. In this case you don´t worry about any data mappers with XML or C# and let NHibernate to generate the database schema from your entities based on a convention that you can customize.
On the other hand learning curve of Linq-to-SQL is smaller then NHibernate.
Or you could use the Castle ActiveRecords project. I've been using that for a short time to ramp up some new code for a legacy project. It uses NHibernate and works on the active record pattern (surprising given its name I know). I haven't tried, but I assume that once you've used it, if you feel the need to drop to NHibernate support directly, it wouldn't be too much to do so for part or all of your project.
As you written "for a person who have not used either of the them"
LINQ to SQL is easy to use so any one can use it easily
It also support procedures, which helps most of the time.
Suppose you want to get data from more than one table then write a procedure and drag that procedure to designer and it will create everything for you,
Suppose your procedure name is "CUSTOMER_ORDER_LINEITEM" which fetch record from all these three table then just write
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
you can use you records object in foreach loop as well, which is not supported by NHibernate

Resources