I have made a some changes for remove converts on join predicates. The way
isn't very formal but it is simple.
I don't know if you know any reason for disagreeing, if so maybe the idea
will inspire to you.

The key problem is in ExpressionDispatcher.Registrar.RegisterAssociation,
when you have to create the Equal expression both columnExpression
parameters should match the type.

Such equal expression won't be very important in the rest of logic flow so
we could fake them creating new ColumnsExpression with the right types.

Index: Data/Linq/Sugar/Expressions/ColumnExpression.cs
===================================================================
--- Data/Linq/Sugar/Expressions/ColumnExpression.cs    (revision 879)
+++ Data/Linq/Sugar/Expressions/ColumnExpression.cs    (working copy)
@@ -56,8 +56,8 @@

         public int RequestIndex { get; set; }

-        public ColumnExpression(TableExpression table, string name,
MemberInfo memberInfo)
-            : base(ExpressionType, memberInfo.GetMemberType())
+        public ColumnExpression(TableExpression table, string name,
MemberInfo memberInfo, bool notNullForJoin)
+            : base(ExpressionType, (memberInfo.GetMemberType().IsNullable()
&& notNullForJoin) ? memberInfo.GetMemberType().GetNullableType() :
memberInfo.GetMemberType())
         {
             Table = table;
             Name = name;
Index: Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs
===================================================================
--- Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs
(revision 879)
+++ Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs
(working copy)
@@ -165,7 +165,7 @@
             if (queryColumn == null)
             {
                 table = RegisterTable(table, builderContext);
-                queryColumn = CreateColumn(table, memberInfo,
builderContext);
+                queryColumn = CreateColumn(table, memberInfo,
builderContext, false);
                 builderContext.CurrentSelect.Columns.Add(queryColumn);
             }
             return queryColumn;
@@ -188,13 +188,13 @@
             return RegisterColumn(tableExpression, memberInfo,
dataMember.MappedName, builderContext);
         }

-        public ColumnExpression CreateColumn(TableExpression table,
MemberInfo memberInfo, BuilderContext builderContext)
+        public ColumnExpression CreateColumn(TableExpression table,
MemberInfo memberInfo, BuilderContext builderContext, bool notNullForJoin)
         {
             var dataMember =
builderContext.QueryContext.DataContext.Mapping.GetTable(table.Type).RowType
                 .GetDataMember(memberInfo);
             if (dataMember == null)
                 return null;
-            return new ColumnExpression(table, dataMember.MappedName,
memberInfo);
+            return new ColumnExpression(table, dataMember.MappedName,
memberInfo, notNullForJoin);
         }

         /// <summary>
@@ -221,7 +221,7 @@
             IList<MemberInfo> theseKeys, otherKeys;
             TableJoinType joinType;
             string joinID;
-            var otherTableType = DataMapper.GetAssociation(tableExpression,
tableMemberInfo, out theseKeys, out otherKeys,
+            var otherTableType = DataMapper.GetAssociation(tableExpression,
tableMemberInfo, out theseKeys, out otherKeys,
                                                       out joinType, out
joinID, builderContext.QueryContext.DataContext);
             // if the memberInfo has no corresponding association, we get a
null, that we propagate
             if (otherTableType == null)
@@ -240,17 +240,20 @@
             for (int keyIndex = 0; keyIndex < theseKeys.Count; keyIndex++)
             {
                 // joinedKey is registered, even if unused by final select
(required columns will be filtered anyway)
-                Expression otherKey = RegisterColumn(otherTableExpression,
otherKeys[keyIndex], builderContext);
+                ColumnExpression otherKey =
RegisterColumn(otherTableExpression, otherKeys[keyIndex], builderContext);
                 // foreign is created, we will store it later if this
assocation is registered too
-                Expression thisKey = CreateColumn(tableExpression,
theseKeys[keyIndex], builderContext);
-                createdColumns.Add((ColumnExpression)thisKey);
+                ColumnExpression thisKey = CreateColumn(tableExpression,
theseKeys[keyIndex], builderContext, false);
+                createdColumns.Add(thisKey);

                 // if the key is nullable, then convert it
-                // TODO: this will probably need to be changed
+
                 if (otherKey.Type.IsNullable())
-                    otherKey = Expression.Convert(otherKey,
otherKey.Type.GetNullableType());
+                    //this column will replace the original one for the
equal expression. It won't be registered
+                    otherKey = CreateColumn(otherKey.Table,
otherKey.MemberInfo, builderContext, true);
                 if (thisKey.Type.IsNullable())
-                    thisKey = Expression.Convert(thisKey,
thisKey.Type.GetNullableType());
+                    //this column will replace the original one for the
equal expression. It won't be registered
+                    thisKey = CreateColumn(thisKey.Table,
thisKey.MemberInfo,builderContext, true);
+
                 var referenceExpression = Expression.Equal(thisKey,
otherKey);

                 // if we already have a join expression, then we have a
double condition here, so "AND" it





On Sun, Sep 14, 2008 at 9:12 PM, Pascal Craponne <[EMAIL PROTECTED]> wrote:

>
> Yes, I came to the same conclusion a few minutes ago :(
> And the CONVERT won't probably help, maybe we should work on
> optimizing the use of CONVERT first.
>
> On 14 sep, 20:16, "Pablo Iñigo Blasco" <[EMAIL PROTECTED]> wrote:
> > On Sun, Sep 14, 2008 at 7:42 PM, Pascal Craponne <[EMAIL PROTECTED]>
> wrote:
> >
> > > It appears that the test  also fails with linq-to-SQL, which makes me
> think
> > > that there should not at all be an outer join here (I'll investigate a
> bit
> > > further anyway). If I'm right, the test is wrong and we'll need to fix
> it.
> >
> > it is working for my linq2sql.
> > this is the sample:
> >
> >  var query = from e in db.Employees
> >                         select new
> >                         {
> >                             Name = e.FirstName,
> >                             ReportsTo = e.ReportsToEmployee.FirstName
> >                         };
> >
> > this is our generated sql for mssql:
> >
> > SELECT e$.[FirstName], t1$.[FirstName]
> > FROM [dbo].[Employees] e$, [dbo].[Employees] t1$
> > WHERE CONVERT(int,e$.[ReportsTo]) = t1$.[EmployeeID]
> > 2008-09-14 20:08:11Z Select SQL: SELECT e$.[FirstName], t1$.[FirstName]
> > FROM [dbo].[Employees] e$, [dbo].[Employees] t1$
> > WHERE CONVERT(int,e$.[ReportsTo]) = t1$.[EmployeeID]
> >
> > it fails in the assertion:
> > Assert.AreEqual(3, list.Count)
> >
> > this is linq2sql generated sql:
> >
> > SELECT [t0].[FirstName] AS [Name], [t1].[FirstName] AS [ReportsTo]
> > FROM [dbo].[Employees] AS [t0]
> > LEFT OUTER JOIN [dbo].[Employees] AS [t1] ON [t1].[EmployeeID] =
> > [t0].[ReportsTo]
> >
> > it doesn't fail in the assertion.
> >
> > Therefore outter joins should be implicit created.
> > Regards.
> >
>


-- 
Saludos. Pablo Iñigo Blasco .

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"DbLinq" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/dblinq?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to