views:

129

answers:

2

While trying a sem-complex query to display some ListView content on the page I got stuck on the famous "Only parameterless contstructor and initializers are supported in LINQ to Entities" error.

Here is the code I used ... I can't find a place where I initialized something inside the query with parameters ....

protected void ArtistsList()
{
    Guid cat1 = new Guid("916ec8ae-8336-43b1-87c0-8536b2676560");
    Guid cat2 = new Guid("92f2a07f-0570-4521-870a-bf898d1e92d6");

    var memberOrders = (from o in DataContext.OrderSet
                        where o.Status == 1 || o.Status == 0
                        select o.ID);

    var memberOrderDetails = (from o in DataContext.OrderDetailSet
                              where memberOrders.Any(f => f == o.Order.ID)
                              select o.Product.ID );

    var inventoryItems = (from i in DataContext.InventoryItemSet
                          select i.Inventory.Product.ID);

    var products = (from p in DataContext.ProductSet
                    join m in DataContext.ContactSet on p.ManufacturerID equals m.ID
                    where p.Active == true
                       && p.ShowOnWebSite == true
                       && p.Category.ID != cat1
                       && p.Category.ID != cat2
                       && p.AvailableDate <= DateTime.Today
                       && (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
                       && memberOrderDetails.Any(f => f != p.ID)
                       && inventoryItems.Any(f => f == p.ID)
                    select new { ContactID = m.ID, ContactName = m.Name });

    artistsRepeater.DataSource = products;
    artistsRepeater.DataBind();

    Response.Write("PRODUCT COUNT: " + products.Count());
}

The error itself pops on the line artistsRepeater.DataSource = products;

I tried to comment the lines && memberOrderDetails.Any(f => f != p.ID) and && inventoryItems.Any(f => f == p.ID) , still doesn't change anything

Any hints ?

[edit]

With LINQpad, it works with the join but with it is bugging on the commented line

(from p in Products
join m in Members on p.ManufacturerID.Value equals m.ID
where p.Active == true
&& p.ShowOnWebSite == true
&& p.AvailableDate <= DateTime.Today
&& (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
//&& (from od in MemberOrderDetails where (from mo in MemberOrders where mo.Status == 1 || mo.Status == 0 select mo.ID).Any(f => f == od.ID) select od.Product.ID)
&& (from inv in InventoryItems select inv.Inventory.ProductID).Any(i => i.Value == p.ID)
select m).Distinct()

[edit-2]

It seems that this query in LINQpad is ok :

(from p in Products
join m in Members on p.ManufacturerID.Value equals m.ID
where p.Active == true
&& p.ShowOnWebSite == true
&& p.AvailableDate <= DateTime.Today
&& (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
&& !(from od in MemberOrderDetails where (from mo in MemberOrders where mo.Status == 1 || mo.Status == 0 select mo).Any(f => f.ID == od.ID) select od.Product.ID).Any(i => i == p.ID)
&& (from inv in InventoryItems select inv.Inventory.ProductID).Any(i => i.Value == p.ID) 
select m)
+1  A: 

The most likely culprit is:

select new { ContactID = m.ID, ContactName = m.Name }

This is because anonymous types do not have parameterless constructors. What's odd about that is that anonymous types are de riguer in LINQ to Entities. I just don't see any other line that could be offending.

First try removing that line and see if the error goes away. At least we'll know if it's that line or not. Then we can focus on figuring out why.

Edit: What are the types of OrderSet.ID, Product.ID and Order.ID and ContactSet.ID? Are any of them Guid and implicitly the Guid constructor is being called?

Jason
well, not quite ... I tried with only "select m" and didn't work either...
Erick
No, this is supported in L2E
Craig Stuntz
Okay, so we are near certain it's not that line? Ugh. This is definitely mysterious.
Jason
@Craig Stuntz: I understand that. Hence the statement "anonymous types are de riguer in LINQ to Entities."
Jason
What are the types of `OrderSet.ID`, `Product.ID` and `Order.ID`? Are any of them `Guid` and implicitly the `System.Guid` constructor is being called?
Jason
I'm interested in seeing if he can do a watch on products and expand it and see the entire collection...
Terry Donaghe
@Jason all of them are guid you are right. For the constructor part tho I can't say.
Erick
@Terry, can't debug the website, I'm based on a 3rd party ERP that can't be compiled/transformed in web application :/
Erick
How about doing a Response.Write and try to spit out a list of the product IDs. That would see if we're blowing up for sure on products
Terry Donaghe
@Jason tried to only select m and still it blows. Tho I already worked with L2E with Guid and they seemed to work ...
Erick
+1  A: 

OK, this is subtle, but what if you change your LINQPad query from:

           (from p in Products
            join m in Members 
                on p.ManufacturerID.Value equals m.ID
            where p.Active == true
                && p.ShowOnWebSite == true
                && p.AvailableDate <= DateTime.Today
                && (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
                && (from od in MemberOrderDetails 
                    where (from mo in MemberOrders 
                           where mo.Status == 1 || mo.Status == 0 
                           select mo.ID).Any(f => f == od.ID) 
                    select od.Product.ID)
                && (from inv in InventoryItems 
                    select inv.Inventory.ProductID).Any(i => i.Value == p.ID)

...to:

           (from p in Products
            join m in Members 
                on p.ManufacturerID.Value equals m.ID
            where p.Active == true
                && p.ShowOnWebSite == true
                && p.AvailableDate <= DateTime.Today
                && (p.DiscontinuationDate == null || p.DiscontinuationDate >= DateTime.Today)
                && (from od in MemberOrderDetails 
                    where (from mo in MemberOrders 
                           where mo.Status == 1 || mo.Status == 0 
                           select mo).Any(f => f.ID == od.ID)          // NOTE!
                    select od.Product.ID)
                && (from inv in InventoryItems 
                    select inv.Inventory.ProductID).Any(i => i.Value == p.ID)

Why? I think type inference might be doing you wrong here. I've seen a similar thing with DateTimes.

Craig Stuntz
There is no `Manufacturer` proprety in the ProductSet class that is why I *have* to pass by a join query ... no choice here
Erick
OK, try the edit. I'd fix that missing property, though. :)
Craig Stuntz
Meh still have the same error with your code -_-"
Erick
If so, that is nasty that you have to do that. What is the underlying cause? Is there something special about `struct` that makes this necessary (or is it merely a coincidence that `Guid` and `DateTime` are `struct`?)?
Jason
I don't think it's `struct` that's the issue. But I'm not totally certain what the issue is. I *think* it has to do with the nullability. But like I said, I don't totally understand what's going on.
Craig Stuntz
I edited with the query tweaked a bit and it *seems* to work here
Erick
@Erick and @Jason, I'm wondering if this is related: http://stackoverflow.com/questions/2088231/expression-greaterthan-fails-if-one-operand-is-nullable-type-other-is-non-nullab/2088849#2088849
Craig Stuntz
@Craig tried it, (Guid? manufacturerID = new Guid?(new Guid("theguid")); and resulted with a "A severe error occurred on the current command. The results, if any, should be discarded." error...
Erick
@Craig, more fun to come ! Basically, this source is sent on a ListView, which contains another ListView that calls a method for his datasource. If I null the other method everything is cool but otherwise it just doesn't like it at all.
Erick
Not exactly that the answer but I finally rewrited the whole page (was working from another guy's work) ... Basically there was a ListView inside a ListView inside another ListView (go figure...). Now it's working perfecly with only a ListView and a repeater inside the LV.
Erick
@Craig Stuntz: Yes, that could be if the corresponding table field is declared as, say, `uniqueidentifier NULL`. Yucky.
Jason