Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>There's no such thing</h2> <p>Each person has their own definition of what features a 100% implemented LINQ provider should have. One might expect a LINQ provider to be able to translate <code>String.Equals(String, String, StringComparison)</code> to a SQL expression that uses the correct collation, but unless the programmers who created the LINQ provider programmed it to do so, it's not going to be able to do it. There is no end to the things we might want a LINQ provider to be able to do, so <strong>every</strong> LINQ provider has limitations. There is no such thing as 100% when it comes to LINQ providers. It is an unattainable concept. It is infinity.</p> <p>Thus, it is important to...</p> <ol> <li>know the limitations of your LINQ provider, and</li> <li>know how to work around those limitations.</li> </ol> <h2>Limitations</h2> <p>With NHibernate, knowing the limitations is a bit harder than it should be, because there is currently no official documentation for the NHibernate LINQ provider. (<a href="https://nhibernate.jira.com/browse/NH-2444" rel="nofollow noreferrer">NH-2444</a>, patches are welcome!) However, you can figure some of it out just by knowing that this LINQ provider is built on top of HQL, so any limitations that HQL has, LINQ will have as well.</p> <p>There is no NHibernate query syntax that directly supports performing arbitrary left outer joins on unrelated columns (besides Native SQL, of course). Queries in NHibernate are designed so that all of the information to perform a join is already stored in the mappings. After that, all you have to do is specify the relationship, such as <code>order.Customer</code>, and NHibernate knows which tables and columns to join together. You should be able to do arbitrary <em>cross</em> joins using HQL or LINQ, and then you could add a where clause to make it behave like an inner join, but no left outer join.</p> <p>Since none of the query syntaxes directly support what you want to do, building a LINQ/QueryOver wrapper (as apposed to the existing LINQ/HQL wrapper, and probably just as complex to implement) will gain you nothing. You'll have to take the same steps to deal with this query whether you're using LINQ or QueryOver.</p> <h2>Workarounds</h2> <p>Since it is not possible for a LINQ provider to be complete, a well designed LINQ provider must be extensible. That way, if the LINQ provider doesn't natively support the functionality you need, it doesn't ruin your day. The NHibernate LINQ provider <em>can</em> be extended. See <a href="http://www.primordialcode.com/blog/post/nhibernate-3-extending-linq-provider-fix-notsupportedexception" rel="nofollow noreferrer">Giorgetti Alessandro's blog</a> for more information.</p> <p>But of course, before we go off writing LINQ provider extensions, we should check to see if there's a simpler way to solve the problem. A couple of possibilities come to mind:</p> <p>The easiest way to handle this is to simply add the relationship to your NHibernate mappings, enabling you to leverage it in NHibernate queries (LINQ, or whatever). If the two columns are of incompatible data types, or require some kind of manipulation before you can perform the join, consider fixing the data and the schema in order to enable a smoother mapping.</p> <p>Another option is to get creative with subqueries or use multiple queries to emulate what your desired join would do. For example, see one of my <a href="https://stackoverflow.com/questions/18743722/is-a-person-an-aggregate-root/18746408#18746408">other answers</a>:</p> <blockquote> <p>... this LEFT OUTER JOIN can be simulated by combining the results of two separate queries - one to get the orders...</p> <pre><code>var orders = session.Query&lt;OrderHeader&gt;() .Fetch(x =&gt; x.CreatedBy); </code></pre> <p>... and another to get the people that have no orders:</p> <pre><code>var peopleWithNoOrders = session.Query&lt;Person&gt;() .Where(p =&gt; !session.Query&lt;OrderHeader&gt;().Any(o =&gt; o.CreatedBy == p)); </code></pre> </blockquote> <p>... because a <code>left outer join</code> is equivalent to an <code>inner join</code> plus additional results for non-matches. I don't know the details of the join you're trying to perform, but hopefully this will give you enough ideas to get started.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload