0

I'm using ServiceStack OrmLite JoinSQLBuilder with a left join and have found an issue. Suppose I have 2 tables, TableA and TableB and wanted to join on more than a single value.

In SQL I would do something like this:

SELECT  
    TableA.Name, 
    TableB.Value
FROM    
    TableA
LEFT JOIN 
    TableB 
ON     
    TableB.AId = TableA.Id
    AND TableB.PostCode = '12345'  

Now the JoinSQLBuilder only allows joins on a single column and generates SQL like so

SELECT  
    TableA.Name, 
    TableB.Value
FROM    
    TableA
LEFT JOIN 
    TableB 
ON     
    TableB.AId = TableA.Id
WHERE
    TableB.PostCode = '12345'  

Which is not the same thing at all!

Is there any way around this in ServiceStack OrmLite? Here is an example of left joins with where clauses: Left Join With Where Clause

Community
  • 1
  • 1
Bob
  • 3,074
  • 11
  • 43
  • 62

1 Answers1

1

You should be able to use the new support for JOIN's in OrmLite's Typed SqlExpressions. It's best to use the latest v4.0.23 release on MyGet which includes improved support for selecting multiple columns across joined tables.

With the new JOIN API's you can do what you need with something like:

public class TableA
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class TableB
{
    public int AId { get; set; }
    public string PostCode { get; set; }
    public string Value { get; set; }
}

public class TableABFields
{
    public string TableAName { get; set; }
    public string TableBValue { get; set; }
}

var results = db.Select<TableABFields,TableA>(q =>
    q.Join<TableA,TableB>((a,b) => b.AId == a.Id && b.PostCode == "12345"));

Alternative API using an explicit SQL Expression:

var q = db.From<TableA>();
// or 
var q = OrmLiteConfig.DialectProvider.SqlExpression<TableA>();


q.Join<TableA,TableB>((a,b) => b.AId == a.Id && b.PostCode == "12345");

var results = db.Select(q);
mythz
  • 141,670
  • 29
  • 246
  • 390
  • It would be nice to be able to build up a predicate without needing the "db" to join onto. For example, build the join in a repository layer before passing it to the data access. db.Join(predicate); – Bob Jun 25 '14 at 11:44
  • Thanks for that - I've got the layers working well. After updating to the latest version though, I get the error "Method not found: 'Void ServiceStack.OrmLite.SqlExpression`1..ctor()'." on a call from connection.Single(x => x.Id == id && x.IsDeleted == false); – Bob Jun 25 '14 at 15:46
  • @ByronCobb that's indicative of a dirty version mismatch issue. I've just [Created a new Console App for this](https://gist.github.com/mythz/2fd115956d57bb684787) using the [MyGet package](https://github.com/ServiceStack/ServiceStack/wiki/MyGet) and it works as expected. Make sure all your packages were updated, otherwise I'd do a clean reinstall of all ServiceStack packages. – mythz Jun 26 '14 at 10:01
  • Thanks, that was the issue. I keep finding more though - should I start a new question? It doesn't seem that I can use inherited class values anymore => TableA : BaseEntity => BaseEntity.IsDeleted = MySql.Data.MySqlClient.MySqlException : Unknown column 'BaseEntity.IsDeleted' in 'where clause' – Bob Jun 26 '14 at 11:27
  • @ByronCobb yeah can you open up a new question with the exception and source code that creates the error. – mythz Jun 26 '14 at 12:41
  • thank you, http://stackoverflow.com/questions/24431135/servicestack-ormlite-joins-on-child-classes – Bob Jun 26 '14 at 12:56