On Wed, 2010-06-23 at 19:59 -0700, xanadont wrote:
> Yep, here you go:

Perhaps unsurprisingly, that stack trace isn't entirely helpful as it
lacks line numbers.  It does provide some help, though, in that it
raises a question:  WHY is it in SqlProvider.GetLiteral()?!

SqlProvider.GetLiteral() is for getting literals, like '1', not for
creating instances.

A more complete example may be in order.  For example, given your
original sample:

        var mine = from i in Context.Items
                   select new MyItem
                   {
                       Id = i.ID,
                       Value = i.Value
                   };

Our unit tests already contain similar tests, e.g. in
ReadTest_Operands.cs:H4_Select_MemberInit_Class() [0]

        [Test]
        public void H4_Select_MemberInit_Class()
        {
            Northwind db = CreateDB();
            var q = from p in db.Products
                    where p.ProductID > 5
                    select new ProductWrapper2 { ProductID = (int)p.ProductID, 
SupplierID = (int?)p.SupplierID };
            int count = 0;
            foreach (ProductWrapper2 p in q)
            {
                Assert.IsTrue(p.ProductID > 5, "Failed on ProductID>=20");
                count++;
            }
            Assert.IsTrue(count > 0, "Expected some products with ProductID>5, 
got none");
        }

Furthermore, IL-wise every anonymous class is an actual named class
(just with a name that you can't express in C#), so every 'select new
{...}' expression also needs to hit the same code path...

My assumption is that you're not actually calling 'new' within a select
block, but within a 'where' block; for example, I'm able to get the same
exception message message and stack trace with:

            Northwind db = CreateDB();
            var q = from p in db.Products
                    where p.ProductID > new Nullable<int>(5).Value
                    select new ProductWrapper3(
                        (int)p.ProductID, (int?)p.SupplierID);

The issue above is the 'new' within the 'where'.  The workaround, of
course, is to avoid using 'new' outside of the 'select' expression.

This issue has been added to:

        http://code.google.com/p/dblinq2007/issues/detail?id=260

As for fixing it, (1) I'm not entirely sure what this entails; (2) I'm
going on vacation soon; and (3) I'm currently working on another
project.  Sorry. :-/

> I'm not sure what you mean by "with the exception that you can't use
> 'new' to create new Entity instances"

An entity is a type that the DataContext has a type mapping for
(specifically that DataContext.Mapping.GetMetaType(Type) returns a
non-null value for), e.g. every type that is exposed by DataContext
fields and properties (when using AttributeMappingSource).

The reason for this is that DataContext needs to keep a reference to
every entity type it creates for change-tracking purposes (e.g. you
update a property value then call DataContext.SubmitChanges() to commit
the property values), and one of the features of selecting a specific
type is that you disable change tracking; if you could select on an
entity type, you wouldn't actually disable change tracking (as the
DataContext wouldn't know that in this situation you didn't want change
tracking), which could result in hard to understand bugs.

 - Jon

[0]
http://dblinq2007.googlecode.com/svn/trunk/src/DbLinq/Test/Providers/ReadTest_Operands.cs


-- 
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