2

I've Googled this error and read some posts here on stack overflow as well but i still do not understand what the problem is here. I understand the "english" but not the programmatic reasoning. Why can I do this:

 public void FillRegister(ItemMovementRegister register, IDateRange imqp)
        {
            var f = from detail in this.Context.ItemMovements
                    where (detail.MovementDate >= imqp.StartDate) &&
                            (detail.MovementDate <= imqp.EndDate)
                    orderby detail.MovementDate descending
                    select new ItemMovement(detail.SourceSystemId,
                                            (ItemMovementKind)detail.MovementKind,
                                            detail.MovementDate.DateTime,
                                            detail.UniversalMovementKey,
                                            detail.UniversalMaterialItemKey,
                                            ((detail.SourceDocumentRef != null) ? detail.SourceDocumentRef.Trim() : string.Empty),
                                            ((detail.SourceComment != null) ? detail.SourceComment.Trim().Replace("Sale: ", "").Substring(0, 20) : string.Empty),
                                            detail.ActualDeltaQty)
                        {
                            MovementKindName = detail.MovementKindName.Trim()
                        };
            register.AddRange(f.ToList<ItemMovement>());
        }

but not this:

public void FillRegister(ItemMovementRegister register, IDateRange imqp)
        {
            try
            {
                var f = from detail in this.Context.ShippingDocumentDetails
                        join header in this.Context.ShippingDocuments on detail.ClientOrderNumber equals header.ClientOrderNumber
                        where (header.DateOrdered >= imqp.StartDate)
                         && (header.DateOrdered <= imqp.EndDate)
                        orderby header.DateOrdered descending
                        select new ItemMovement(long.Parse(ConfigurationManager.AppSettings["PickedOrderSourceSystem"]),
                            ItemMovementKind.Picked,
                            ((header.DateOrdered.HasValue) ? header.DateOrdered.Value : new DateTime(1900, 1, 1)),
                             UniversalItemMovementConverter.GetMovementKeyFromShippingDocument(header.ClientOrderNumber),
                            detail.ProductCode,
                            header.ClientOrderNumber,
                            string.Empty,
                            ((detail.QuantityDelivered.HasValue) ? detail.QuantityDelivered.Value : 0)) { };
                List<ItemMovement> ms = f.ToList<ItemMovement>(); // Fails here
                this.UpdateItemMovements(ms);
                register.AddRange(ms);
            }
            catch (Exception ex)
            {
                throw new DALException("void FillItemMovements(ItemMovementRegister register, IDateRange imqp) failed :" + ex.Message, ex);
            }
        }  
rism
  • 11,932
  • 16
  • 76
  • 116
  • 1
    I've never understood it either, but you can't use a LINQ type in your `select` unless it is the actual type being selected. You will have to settle for a custom class structure made for the return value, or an anonymous class. – mellamokb Apr 20 '12 at 03:29
  • If you put that as the answer I will accept. It's the clearest explaination I've seen. Simple Two sentences. From that I can move forward. If thats the rule then fine, I've just never seen it stated anywhere that clearly. Thnx – rism Apr 20 '12 at 05:02
  • possible duplicate of [The entity cannot be constructed in a LINQ to Entities query](http://stackoverflow.com/questions/5325797/the-entity-cannot-be-constructed-in-a-linq-to-entities-query) – Gert Arnold Apr 21 '12 at 19:48
  • @mellamokb: As far as I know (and see happening) you can't even create a linq entity when it is the type selected. [This comment](http://stackoverflow.com/questions/5325797/the-entity-cannot-be-constructed-in-a-linq-to-entities-query#comment8054017_5325861) explains it very well. It is entity framework, but the same principles apply. – Gert Arnold Apr 21 '12 at 19:50

1 Answers1

0

I've had better luck with constructs like this:

var ms = (from detail in this.Context.ShippingDocumentDetails
                    join header in this.Context.ShippingDocuments on detail.ClientOrderNumber equals header.ClientOrderNumber
                    where (header.DateOrdered >= imqp.StartDate)
                     && (header.DateOrdered <= imqp.EndDate)
                    orderby header.DateOrdered descending
                    select new ItemMovement(long.Parse(ConfigurationManager.AppSettings["PickedOrderSourceSystem"]),
                        ItemMovementKind.Picked,
                        ((header.DateOrdered.HasValue) ? header.DateOrdered.Value : new DateTime(1900, 1, 1)),
                         UniversalItemMovementConverter.GetMovementKeyFromShippingDocument(header.ClientOrderNumber),
                        detail.ProductCode,
                        header.ClientOrderNumber,
                        string.Empty,
                        ((detail.QuantityDelivered.HasValue) ? detail.QuantityDelivered.Value : 0)) { }).ToList();
            this.UpdateItemMovements(ms);
            register.AddRange(ms);

I'm a little fuzzy on some parts of this subject, but I think it has something to do with deferred execution. You may even have better luck if you had changed the problem line to this:

var ms = new List<ItemMovement>(f.ToList());

You may not even need to f.ToList(). Just f might be enough. Someone more versed in this subject may be able to explain more fully, but I believe it has to do with forcing some sort of instantiation of an object.

urbadave
  • 231
  • 1
  • 3
  • 9
  • That wouldn't work because the update would be updating the result of the query and then you pass the query again to AddRange which would be sans the update. i.e. different instances. – rism Apr 20 '12 at 05:00