473,386 Members | 1,699 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Simulating an outer non-equijoin in LINQ.

Question: Can an outer non-equijoin be simulated using LINQ?

It's quite unfortunate that LINQ doesn't support literal joins based on
anything other than equality. I know that this the most common scenario, and
although the efficiency of other types of joins is often debatable, they are
often darned useful. In T-SQL I have dozens of such useful queries with
joins based on such operations as prefix or suffix comparisons (using the
LIKE operator) and even bitmask comparisons.

In LINQ, one can clearly achieve the following:
(a) An outer equality-based join can be simulated using the "join" operator
in conjunction with the DefaultIfEmpty() method.

(b) One can simulate an inner join based on something other than equality,
for example:

string[] words ={"walking,"bouncing","bounced","bounce","talked", "running"};

string[] suffixes = {"ing","ed","er","iest"};

....and we wish to return all words paired with their suffixes, we could use:
var pairs = from a in words from b in suffixes where a.EndsWith(b) select
new {a, b};

- but we'd only get an inner join. The word "bounce" would not be returned.
(In an outer join "bounce" would be returned paired with a null.)

Is there any way, in LINQ, of at least simulating an outer join based on
something other than equality?
Dec 4 '07 #1
7 4169
On Dec 4, 4:05 pm, Tom Bombadil
<TomBomba...@discussions.microsoft.comwrote:
Question: Can an outer non-equijoin be simulated using LINQ?
<snip>

Can you say *exactly* what you'd want the sequence of results to be?
If you could put it together in a LINQ to Objects short but complete
program, that would be even better.

I'm sure it's possible, but:

1) Using the standard query operators it's probably ugly
2) You could write your own extensions to make it more pleasant in
LINQ to Objects
3) I've no idea whether the standard query operators version would
work in LINQ to SQL

When you've specified exactly what you want the results to be (and
when I'm at home) I'll have a look.

(My guess is that you want all the matching suffixes, or null if there
aren't any, that using a "group by" and then DefaultIfEmpty() would
work - that's a way of doing something approaching an outer join.)

Jon
Dec 4 '07 #2
In the example given what I would want to retrieve from query would be:

{ a = walking, b = ing }
{ a = walked, b = ed }
{ a = bouncing, b = ing }
{ a = bounced, b = ed }
{ a = bounce, b = (null) }
{ a = talked, b = ed }
{ a = running, b = ing }

This is typical outer join behavior - all parent records are returned even
if there is no match, in which case any selected child fields are returned as
nulls.
"Jon Skeet [C# MVP]" wrote:
On Dec 4, 4:05 pm, Tom Bombadil
<TomBomba...@discussions.microsoft.comwrote:
Question: Can an outer non-equijoin be simulated using LINQ?

<snip>

Can you say *exactly* what you'd want the sequence of results to be?
If you could put it together in a LINQ to Objects short but complete
program, that would be even better.

I'm sure it's possible, but:

1) Using the standard query operators it's probably ugly
2) You could write your own extensions to make it more pleasant in
LINQ to Objects
3) I've no idea whether the standard query operators version would
work in LINQ to SQL

When you've specified exactly what you want the results to be (and
when I'm at home) I'll have a look.

(My guess is that you want all the matching suffixes, or null if there
aren't any, that using a "group by" and then DefaultIfEmpty() would
work - that's a way of doing something approaching an outer join.)

Jon
Dec 4 '07 #3
Tom Bombadil <To*********@discussions.microsoft.comwrote:
In the example given what I would want to retrieve from query would be:

{ a = walking, b = ing }
{ a = walked, b = ed }
{ a = bouncing, b = ing }
{ a = bounced, b = ed }
{ a = bounce, b = (null) }
{ a = talked, b = ed }
{ a = running, b = ing }

This is typical outer join behavior - all parent records are returned even
if there is no match, in which case any selected child fields are returned as
nulls.
Okay - will look at it later. Definitely doable.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Dec 4 '07 #4
Tom Bombadil <To*********@discussions.microsoft.comwrote:
In the example given what I would want to retrieve from query would be:

{ a = walking, b = ing }
{ a = walked, b = ed }
{ a = bouncing, b = ing }
{ a = bounced, b = ed }
{ a = bounce, b = (null) }
{ a = talked, b = ed }
{ a = running, b = ing }

This is typical outer join behavior - all parent records are returned even
if there is no match, in which case any selected child fields are returned as
nulls.
Done:

using System;
using System.Collections.Generic;
using System.Linq;

class Test
{
static void Main()
{
string[] words = {"walking","bouncing","bounced",
"bounce","talked","running"};
string[] suffixes = {"ing","ed","er","iest"};

var query = from word in words
from suffix in suffixes.Where(x =>word.EndsWith(x))
.DefaultIfEmpty()
select new { a = word, b = suffix };

foreach (var result in query)
{
Console.WriteLine (result);
}
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Dec 4 '07 #5
Thanks. That does, in fact, do the trick.
It does answer my question as a basic proof-of-concept, and it's an example
that's missing from the current literature.

Now a more difficult practicality arises when attempting this particular
sort of join between a local object (as parent) and a SQL table (as child).
When such an attempt is made, the following exception is generated: "Only
arguments that can be evaluated on the client are supported for the
String.EndsWith method." An attempt to use the
not-actually-supported-for-direct-use SqlMethods.Like() static method almost
does the trick, but not quite due to null-object issues...I'll keep working
on it.

Thanks again.

"Jon Skeet [C# MVP]" wrote:
Tom Bombadil <To*********@discussions.microsoft.comwrote:
In the example given what I would want to retrieve from query would be:

{ a = walking, b = ing }
{ a = walked, b = ed }
{ a = bouncing, b = ing }
{ a = bounced, b = ed }
{ a = bounce, b = (null) }
{ a = talked, b = ed }
{ a = running, b = ing }

This is typical outer join behavior - all parent records are returned even
if there is no match, in which case any selected child fields are returned as
nulls.

Done:

using System;
using System.Collections.Generic;
using System.Linq;

class Test
{
static void Main()
{
string[] words = {"walking","bouncing","bounced",
"bounce","talked","running"};
string[] suffixes = {"ing","ed","er","iest"};

var query = from word in words
from suffix in suffixes.Where(x =>word.EndsWith(x))
.DefaultIfEmpty()
select new { a = word, b = suffix };

foreach (var result in query)
{
Console.WriteLine (result);
}
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Dec 4 '07 #6
Tom Bombadil <To*********@discussions.microsoft.comwrote:
Thanks. That does, in fact, do the trick.
It does answer my question as a basic proof-of-concept, and it's an example
that's missing from the current literature.

Now a more difficult practicality arises when attempting this particular
sort of join between a local object (as parent) and a SQL table (as child).
When such an attempt is made, the following exception is generated: "Only
arguments that can be evaluated on the client are supported for the
String.EndsWith method." An attempt to use the
not-actually-supported-for-direct-use SqlMethods.Like() static method almost
does the trick, but not quite due to null-object issues...I'll keep working
on it.
Hmm... that suggests that you can't use String.EndsWith for two fields
even outside a join, for instance:

from user in users
where user.FullName.EndsWith(user.Surname)
select user;

Does that work?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Dec 4 '07 #7
Tom Bombadil wrote:
Thanks. That does, in fact, do the trick.
It does answer my question as a basic proof-of-concept, and it's an
example that's missing from the current literature.

Now a more difficult practicality arises when attempting this
particular sort of join between a local object (as parent) and a SQL
table (as child). When such an attempt is made, the following
exception is generated: "Only arguments that can be evaluated on the
client are supported for the String.EndsWith method." An attempt to
use the not-actually-supported-for-direct-use SqlMethods.Like()
static method almost does the trick, but not quite due to null-object
issues...I'll keep working on it.
That's not possible. What you need in that case is either:
1) a temptable in where you insert the in-memory objects, then join
with that temptable and select from that join
or
2) use an IN query (.Contains(set)) with PK values and filter on the
child's fk field values.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Dec 5 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: mheydman | last post by:
I apologize if this has been asked before- I searched google but could not find a concrete answer. I recently inherited a database whose t-sql code is written in a format that I find difficult...
4
by: thilbert | last post by:
All, I have a perplexing problem that I hope someone can help me with. I have the following table struct: Permission ----------------- PermissionId Permission
3
by: Dam | last post by:
Using SqlServer : Query 1 : SELECT def.lID as IdDefinition, TDC_AUneValeur.VALEURDERETOUR as ValeurDeRetour FROM serveur.Data_tblDEFINITIONTABLEDECODES def,...
3
by: Martin | last post by:
Hello everybody, I have the following question. As a join clause on Oracle we use " table1.field1 = table2.field1 (+) " On SQL Server we use " table1.field1 *= table2.field1 " Does DB2...
2
by: dobest03 | last post by:
Hi. Are there any way to access the integer member 'a' of outer structure from inner structure's member function func_inner()? See below the structure... Thanks. struct outer {
1
by: Edward C. Jones | last post by:
#! /usr/bin/env python """ When I run the following program I get the error message: UnboundLocalError: local variable 'x' referenced before assignment Can "inner" change the value of a...
4
by: Roger Withnell | last post by:
I would like to freeze column and row headings on a webpage, simulating freeze panes as in an Excel spreadsheet. Don't seem to be able to do it with Frames. Is there a way with Javascript...
0
by: gr8white | last post by:
I'm running a query involving an outer join where one of the conditions is that the numeric value of a varchar field is between the numeric values of 2 varchar fields in another table (this has to do...
9
by: Matthias Buelow | last post by:
Hi folks, I've got something like: class Outer { int f(); friend class Inner; class Inner { int g() {
3
by: ChrisW | last post by:
Hiya, So I have a class that creates threads within it. These threads are a class underneath the parent class. I want to access values in the parent class from the threads while they run. Yet...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.