Removing the conversion may cause problems (If I remember correctly,
Expressions were not consistent, and we had exceptions).
I'm currently working in a different way: the conversion is emitted in SQL
only when necessary.It is unnecessary if:
- source and target types are the same
- conversion goes from nullable to non-nullable
- conversion goes from non-nullable to nullable.
Maybe we could also add common numeric conversions, if it appears we need
it.
On Sun, Sep 14, 2008 at 22:31, Pablo Iñigo Blasco <[EMAIL PROTECTED]> wrote:
> 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 .
>
> >
>
--
Pascal.
jabber/gtalk: [EMAIL PROTECTED]
msn: [EMAIL PROTECTED]
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---