DbLinq / dblinq2007

LINQ provider for Oracle, PostgreSQL, MySQL, Ingres, SQLite, Firebird and ... SQL Server
Other
62 stars 31 forks source link

Join clause throws 1010 ExpressionType exception #81

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,

When I try to retrieve an associated element with this expression using join
clause

var foos =
from f in db.Foos
join b in db.Bars
on f.BarID equals b.BarID
select new { Foo = f, Bar = b};

and this database

CREATE TABLE IF NOT EXISTS [Foo]
(
    [FooId] GUID UNIQUE NOT NULL PRIMARY KEY,
    [BarId] GUID CONSTRAINT fk_Bar_BarId REFERENCES Bar (BarId)
);

CREATE TABLE IF NOT EXISTS [Bar]
(
    [BarId] GUID UNIQUE NOT NULL PRIMARY KEY
);

I'm getting this exception

1010

   at DbLinq.Vendor.Implementation.SqlProvider.GetLiteral(ExpressionType
operationType, IList`1 p) in
d:\dev\work\colaboration\dblinq\DbLinq\Vendor\Implementation\SqlProvider.cs:line
263
   at
DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.BuildExpression(Expression
expression, QueryContext queryContext) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Sugar\Implementation\SqlBuilder
.cs:line
161
   at
DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.BuildExpression(Expression
expression, QueryContext queryContext) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Sugar\Implementation\SqlBuilder
.cs:line
121
   at
DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.BuildSelect(Expression
select, QueryContext queryContext) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Sugar\Implementation\SqlBuilder
.cs:line
280
   at
DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.Build(SelectExpression
selectExpression, QueryContext queryContext) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Sugar\Implementation\SqlBuilder
.cs:line
80
   at
DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.BuildSelect(ExpressionQuery
expressionQuery, QueryContext queryContext) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Sugar\Implementation\SqlBuilder
.cs:line
67
   at
DbLinq.Data.Linq.Sugar.Implementation.QueryBuilder.BuildSqlQuery(ExpressionQuery
expressionQuery, QueryContext queryContext) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Sugar\Implementation\QueryBuild
er.cs:line
329
   at
DbLinq.Data.Linq.Sugar.Implementation.QueryBuilder.GetSelectQuery(ExpressionChai
n
expressions, QueryContext queryContext) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Sugar\Implementation\QueryBuild
er.cs:line
387
   at DbLinq.Data.Linq.Implementation.QueryProvider`1.GetQuery(Expression
expression) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Implementation\QueryProvider.cs
:line
100
   at
DbLinq.Data.Linq.Implementation.QueryProvider`1.Execute[TResult](Expression
expression) in
d:\dev\work\colaboration\dblinq\DbLinq\Data\Linq\Implementation\QueryProvider.cs
:line
110
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
   at DbLinqTest.Program.Main(String[] args) in
H:\DbLinqTest\Program.cs:line 40

The engine fails on writing the "SELECT" part of sql expression.

I'm using sqlite provider and head version from svn and windows xp.

A test is attached.

Tony 

Original issue reported on code.google.com by tony.h...@gmail.com on 22 Jul 2008 at 4:03

Attachments:

GoogleCodeExporter commented 9 years ago
Joins have been fixed recently. Can you try using the latest SVN version?

Original comment by picrap on 9 Oct 2008 at 12:48

GoogleCodeExporter commented 9 years ago
This issue is still happening.  If you change the join to from a different 
issue 
happens.  Argument type 'DbLinq.Data.Linq.Table`1[Bar]' does not match the 
corresponding member type 'Bar' 

Original comment by godka...@gmail.com on 17 Oct 2008 at 5:01

GoogleCodeExporter commented 9 years ago
Ok, var q = from c in db.Customers
                    join o in db.Orders on c.CustomerID equals o.CustomerID
                    select o;
works, but
var q = from c in db.Customers
                    join o in db.Orders on c.CustomerID equals o.CustomerID
                    select new { c, o };
does not.

Original comment by godka...@gmail.com on 19 Oct 2008 at 7:17

GoogleCodeExporter commented 9 years ago
QueryBuilder.cs:188, expressions variable.

Here is the broken one.
{(dataRecord, mappingContext) => new <>f__AnonymousType47`2
(<>h__TransparentIdentifier0 = [1010], 
x = new Order() {
CustomerID = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,0)), 
EmployeeID = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableNumeric(valueIndex),dataRecord,mappingContext,1), 
Freight = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableNumeric(valueIndex),dataRecord,mappingContext,2), 
OrderDate = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableDateTime(valueIndex),dataRecord,mappingContext,3), 
OrderID = Convert(Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableNumeric(valueIndex),dataRecord,mappingContext,4)), 
RequiredDate = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableDateTime(valueIndex),dataRecord,mappingContext,5), 
ShipAddress = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,6)), 
ShipCity = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,7)), 
ShipCountry = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,8)), 
ShipName = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,9)), 
ShippedDate = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableDateTime(valueIndex),dataRecord,mappingContext,10), 
ShipPostalCode = Convert(Invoke((dataRecord, mappingContext, valueIndex) => 
value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,11)), 
ShipRegion = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,12)), 
ShipVia = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableNumeric
(valueIndex),dataRecord,mappingContext,13)}).<>h__TransparentIdentifier0.c} 
System.Linq.Expressions.LambdaExpression 
{System.Linq.Expressions.Expression<System.Func<System.Data.IDataRecord,DbLinq.D
ata.L
inq.Mapping.MappingContext,nwind.Customer>>}

Here is the non-broken one.
{(dataRecord, mappingContext) => new Order() {
CustomerID = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,0)), 
EmployeeID = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableNumeric(valueIndex),dataRecord,mappingContext,1), 
Freight = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableNumeric(valueIndex),dataRecord,mappingContext,2), 
OrderDate = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableDateTime(valueIndex),dataRecord,mappingContext,3), 
OrderID = Convert(Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableNumeric(valueIndex),dataRecord,mappingContext,4)), 
RequiredDate = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableDateTime(valueIndex),dataRecord,mappingContext,5), 
ShipAddress = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,6)), 
ShipCity = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,7)), 
ShipCountry = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,8)), 
ShipName = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,9)), 
ShippedDate = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableDateTime(valueIndex),dataRecord,mappingContext,10), 
ShipPostalCode = Convert(Invoke((dataRecord, mappingContext, valueIndex) => 
value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,11)), 
ShipRegion = Convert(Invoke((dataRecord, mappingContext, valueIndex) => value
(DbLinq.Data.Linq.Sugar.Implementation.DataRecordReader).GetAsString(dataRecord,

valueIndex, mappingContext),dataRecord,mappingContext,12)), 
ShipVia = Invoke((dataRecord, mappingContext, valueIndex) => 
dataRecord.GetAsNullableNumeric(valueIndex),dataRecord,mappingContext,13)}} 
System.Linq.Expressions.LambdaExpression 
{System.Linq.Expressions.Expression<System.Func<System.Data.IDataRecord,DbLinq.D
ata.L
inq.Mapping.MappingContext,nwind.Order>>}

Original comment by godka...@gmail.com on 19 Oct 2008 at 7:24

GoogleCodeExporter commented 9 years ago
This is reproducible in v0.18 even without joins.

Line that causes the error:
var baz = from t in dc.Bar select new { Foo = t.Name }

It throws an ArgumentException in 
DbLinq.Vendor.Implementation.SqlProvider.GetLiteral
because the operation type that comes in is "New", and there is no 
implementation for
this case:

Line 236:
//case ExpressionType.New:
//    break;

Stack trace:
>
DbLinq.dll!DbLinq.Vendor.Implementation.SqlProvider.GetLiteral(System.Linq.Expre
ssions.ExpressionType
operationType = New, System.Collections.Generic.IList<string> p = Count = 1) 
Line 267    C#

DbLinq.dll!DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.BuildExpression(Syst
em.Linq.Expressions.Expression
expression = {new <>f__AnonymousType0`1(Foo = [1012])},
DbLinq.Data.Linq.Sugar.QueryContext queryContext =
{DbLinq.Data.Linq.Sugar.QueryContext}) Line 161 + 0x1e bytes    C#

DbLinq.dll!DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.BuildExpression(Syst
em.Linq.Expressions.Expression
expression = SpecialExpression Count, DbLinq.Data.Linq.Sugar.QueryContext
queryContext = {DbLinq.Data.Linq.Sugar.QueryContext}) Line 121 + 0xe bytes  C#

DbLinq.dll!DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.BuildSelect(System.L
inq.Expressions.Expression
select = {[1000]}, DbLinq.Data.Linq.Sugar.QueryContext queryContext =
{DbLinq.Data.Linq.Sugar.QueryContext}) Line 280 + 0xe bytes C#

DbLinq.dll!DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.Build(DbLinq.Data.Li
nq.Sugar.Expressions.SelectExpression
selectExpression = {[1000]}, DbLinq.Data.Linq.Sugar.QueryContext queryContext =
{DbLinq.Data.Linq.Sugar.QueryContext}) Line 80 + 0xa bytes  C#

DbLinq.dll!DbLinq.Data.Linq.Sugar.Implementation.SqlBuilder.BuildSelect(DbLinq.D
ata.Linq.Sugar.ExpressionQuery
expressionQuery = {DbLinq.Data.Linq.Sugar.ExpressionQuery},
DbLinq.Data.Linq.Sugar.QueryContext queryContext =
{DbLinq.Data.Linq.Sugar.QueryContext}) Line 67 + 0x1c bytes C#

DbLinq.dll!DbLinq.Data.Linq.Sugar.Implementation.QueryBuilder.BuildSqlQuery(DbLi
nq.Data.Linq.Sugar.ExpressionQuery
expressionQuery = {DbLinq.Data.Linq.Sugar.ExpressionQuery},
DbLinq.Data.Linq.Sugar.QueryContext queryContext =
{DbLinq.Data.Linq.Sugar.QueryContext}) Line 334 + 0x19 bytes    C#

DbLinq.dll!DbLinq.Data.Linq.Sugar.Implementation.QueryBuilder.GetSelectQuery(DbL
inq.Data.Linq.Sugar.ExpressionChain
expressions = ExpressionChain 2 Expression(s), 
DbLinq.Data.Linq.Sugar.QueryContext
queryContext = {DbLinq.Data.Linq.Sugar.QueryContext}) Line 397 + 0x11 bytes C#

DbLinq.dll!DbLinq.Data.Linq.Implementation.QueryProvider<<string>>.GetQuery(Syst
em.Linq.Expressions.Expression
expression =
{value(DbLinq.Data.Linq.Implementation.QueryProvider`1[<>f__AnonymousType0`1[Sys
tem.String]]).Count()})
Line 100 + 0x32 bytes   C#

DbLinq.dll!DbLinq.Data.Linq.Implementation.QueryProvider<<string>>.Execute<int>(
System.Linq.Expressions.Expression
expression =
{value(DbLinq.Data.Linq.Implementation.QueryProvider`1[<>f__AnonymousType0`1[Sys
tem.String]]).Count()})
Line 110 + 0xa bytes    C#
    [External Code] 
    DataAccessLayer.dll!Avalon.DataAccessLayer.DataAccessLayer(string tenantId =
"d63ea18c-5a04-499c-8de9-d438116d3687") Line 27 + 0xd bytes C#
    ConsoleApplication1.exe!ConsoleApplication1.Program.Main(string[] args =
{string[0]}) Line 14 + 0x15 bytes   C#
    [External Code] 

Original comment by ragesh.k...@gmail.com on 27 Jan 2009 at 4:59

GoogleCodeExporter commented 9 years ago
Adding to my previous comment:

This happens only when I try to call Count() on the resulting var.

i.e.,

baz.Count() throws the error, whereas baz.First() works well.

Original comment by ragesh.k...@gmail.com on 31 Jan 2009 at 6:53

GoogleCodeExporter commented 9 years ago
My reply to comment #3 & #5:
This is maybe a medium priority defect, but it will really helps people if 
someone
made an implementation for it.

Original comment by khaerul....@gmail.com on 23 Apr 2009 at 9:38

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
if you make 
[code]
case ExpressionType.New:
    return "";
[/code]

this work.

Maybe this is not a great solution, but, work for me.

Original comment by egon.dad...@gmail.com on 11 Nov 2009 at 10:11

GoogleCodeExporter commented 9 years ago
Same issue when using select new statement in linq query and then calling 
Count() 
method on it.

var linqPosts = from qPost in Context.Posts
                select new Post
                {
                    ID = qPost.ID,
                    Title = qPost.Title,
                    Summary = qPost.Summary,
                    Content = qPost.Content,
                    Author = qPost.Author,
                    DateCreated = qPost.DateCreated
                };

int count = linqPosts.Count();

Original comment by bosak.to...@gmail.com on 2 Dec 2009 at 7:10

GoogleCodeExporter commented 9 years ago
Taking the existing ReadTest.C3_SelectPenIdName() and changing it to use 
.Count() 
instead of a foreach loop will also trigger the error.

Original comment by jonmpr...@gmail.com on 15 Jan 2010 at 9:26

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I was working on that Issue.
There's two situations:
1 - On ordinary queries, when a new expression like "new { name1 = table1, 
name2 = table2}" is used on the select clause.
In this case, the error occur for the method IsMetaTableDefinition. This method 
have a verification that assume the expression like a join complement and, the 
method that called it, based on that decision, returns a MetaTableExpression, 
returned for RegisterMetaTable, making the primary expression get lost and the 
final select imcomplete. To solve this, I did the IsExternalInExpressionChain 
propagate over the join analyse stack trace, when the buildercontext is cloned 
or newQuoted. To be specific, on the methods AnalyzeQuote and AnalyzeJoin, on 
the ExpressionDispatcher.Analyzer.cs

2 - The Count issue.
When a Count method is used, many treatments of the normal case is not done, 
making a NewExpression go until the SqlBuilder. This is a unexpect situation.
To solve this problem, on the SqlProvider.GetLiteral I did a treatment to new 
expressions (it return *), it's solve the count parameter problem.
A where clause can be added if a expressions is passed to the count method, so, 
I create a method called reduce, and I use this on the AnalyzeOperator, to 
reduce the operators of each parameters that, later, will be replaced on the 
expressions in analyze.
Ex:
  (new { name1 = table1, name2 = table2}).name1.id ==> name1.id
  (new { name1 = table1.name, name2 = table2}).name1 ==> name1.name

I don't know if already there's a method to do this, but it's enough to create 
the right Where clause.
The sources I've change is attached.

I'm testing to see if is that enough to solve the problem and if this solution 
don't create another problem.

If someone download the attachment, the best is if you first download and 
replace the cs I shared on this link:
http://code.google.com/p/dblinq2007/issues/detail?can=1&start=0&num=100&q=Contai
ns%20method&colspec=ID%20Type%20Status%20Priority%20Component%20Owner%20Summary&
groupby=&sort=&id=163

Original comment by tos.oliv...@gmail.com on 25 Mar 2012 at 9:36

Attachments:

GoogleCodeExporter commented 9 years ago
Sorry, I found another situation: when is Single or a Count AND the select 
clause is a  new expression like "new { name1 = table1, name2 = table2}".
The analyze to decide if the aliases is a metatableDefinition 
(IsMetaTableDefinition) is very problematic because when the new is on the 
select part and is on the format described, the method consider it like a 
metatable, but it's not... a metatable refer to a join, if I understand well.
The rule to return the metatable just when the expressions analyzed is not the 
last of the ExpressionChain (the IsExternalInExpressionChain thing) works well 
WHEN the last expression is not a Count or Single method call.
To solve this, I create this class variable:
        private static string[] PosLastCalls = new string[]{
            "Count",
            "Single"
        };

And change the expression that's returns the last expression on the 
expressionChain from this:

Expression last = expressions.Last();

to this:

Expression last = expressions.Last(w => w.NodeType != ExpressionType.Call || 
!PosLastCalls.Contains((w as MethodCallExpression).Method.Name));

I also organized better the Reduce method call and I'll upload a cs that I 
forgot :P.

Original comment by tos.oliv...@gmail.com on 25 Mar 2012 at 5:41

Attachments:

GoogleCodeExporter commented 9 years ago
Please, try out the solution on the link below:
http://code.google.com/p/dblinq2007/issues/detail?id=132#c2

Original comment by tos.oliv...@gmail.com on 1 Apr 2012 at 1:15