Issue with use of constant expressions and use of Union or Concat
- There is a known issue with Union and Concat in LINQ to SQL where the use of the same constant value more than once will not produce the expected projection and cause the underlying SQL UNION command to fail. This has been explained as a consequence of early optimization by the query provider and according to Damien Gaurd's thoughtful post this is supposed to be addressed in LINQ to SQL within .NET 4.0. Unfortunately this has been contradicted on this post (ID#355734) on the Microsoft Connect site where a member of the LINQ to SQL team reported "we will not be fixing this in the next release of LINQ to SQL".
Can we get some kind of confirmation on whether this will be addressed in .NET 4.0 and what time frame we are looking at until we will see it come through in public beta's or release candidates?
My only workaround at this point is to use a let statement for every constant that I introduce into my projection for the sake of making my projections similar so that Union and Concat work. Now that I have more than 100 let statements in a particular query I have a feeling that this is contributing to other this other scary TypeLoadException issue that I have just recently began to run into. At this point this bug is affecting my ability to design what is otherwise an elegant data access layer.
Réponses
We did fix some variations of this in .NET 4.0, but I can't tell for sure if your scenario is one of those or not. There is a difference between the Connect bug you mentioned and the query in the forum post you referenced that Damien replied to. Specifically, the forum thread talks about constant values, where the connect bug talks about projections from database tables.
Let me illustrate the point with two similar queries using the same database.
Query 1:
var query1 = from p in context.Products
select new
{
ProductName = p.ProductName,
Prop1 = p.Discontinued,
Prop2 = !p.Discontinued
};
var query2 = from p in context.Products
select new
{
ProductName = p.ProductName,
Prop1 = p.Discontinued,
Prop2 = p.Discontinued
};
var unionQuery = query1.Union(query2);
Query 2:
var query1 = from p in context.Products
select new
{
ProductName = p.ProductName,
Prop1 = true,
Prop2 = false
};
var query2 = from p in context.Products
select new
{
ProductName = p.ProductName,
Prop1 = true,
Prop2 = true
};
var unionQuery = query1.Union(query2);
In .NET 3.5 SP1, both of these queries fail with the error due to the duplicate columns being optimized out of the second query. However, in .NET 4.0, the first one still fails while the second one does not. The scenario in the MSDN forum thread you referenced looks more like the second one to me. The Connect bug specifically references the first scenario.
Any fixes we did for these scenarios should be included in .NET 4.0 Beta 1 if you want to try that out to verify with your particular query.
Thanks,
Sarah Parra
LINQ to SQL Team
Microsoft
This posting is provided "AS IS" with no warranties, and confers no rights.- Marqué comme réponseDamien Guard - MSFTModérateurmercredi 7 octobre 2009 23:57
Toutes les réponses
We did fix some variations of this in .NET 4.0, but I can't tell for sure if your scenario is one of those or not. There is a difference between the Connect bug you mentioned and the query in the forum post you referenced that Damien replied to. Specifically, the forum thread talks about constant values, where the connect bug talks about projections from database tables.
Let me illustrate the point with two similar queries using the same database.
Query 1:
var query1 = from p in context.Products
select new
{
ProductName = p.ProductName,
Prop1 = p.Discontinued,
Prop2 = !p.Discontinued
};
var query2 = from p in context.Products
select new
{
ProductName = p.ProductName,
Prop1 = p.Discontinued,
Prop2 = p.Discontinued
};
var unionQuery = query1.Union(query2);
Query 2:
var query1 = from p in context.Products
select new
{
ProductName = p.ProductName,
Prop1 = true,
Prop2 = false
};
var query2 = from p in context.Products
select new
{
ProductName = p.ProductName,
Prop1 = true,
Prop2 = true
};
var unionQuery = query1.Union(query2);
In .NET 3.5 SP1, both of these queries fail with the error due to the duplicate columns being optimized out of the second query. However, in .NET 4.0, the first one still fails while the second one does not. The scenario in the MSDN forum thread you referenced looks more like the second one to me. The Connect bug specifically references the first scenario.
Any fixes we did for these scenarios should be included in .NET 4.0 Beta 1 if you want to try that out to verify with your particular query.
Thanks,
Sarah Parra
LINQ to SQL Team
Microsoft
This posting is provided "AS IS" with no warranties, and confers no rights.- Marqué comme réponseDamien Guard - MSFTModérateurmercredi 7 octobre 2009 23:57
- Thanks for clarifying the difference between the two different issues. I welcome any improvement on either of these two issues since it should help to simplify many of our queries. A great example is that solving the second case that you have illustrated will remove the need for us to use hacks that consist of over use of the let keyword to achieve the queries we are looking for.
As soon as I get the chance I'll test the two scenarios in VS 2010 Beta1 and I'll report back my findings.

