The entity cannot be constructed in a LINQ to Entities query

前端 未结 14 2055
失恋的感觉
失恋的感觉 2020-11-21 06:04

There is an entity type called Product that is generated by entity framework. I have written this query

public IQueryable GetProdu         


        
相关标签:
14条回答
  • 2020-11-21 06:37

    It won't let you map back onto Product since that is your table you are querying. You need an anonymous function, then you can add it to a ViewModel, and add each ViewModel to a List<MyViewModel> and return these. It's a slight digression, but I include caveats about handling nullable dates because these are a pain in the behind to deal with, just in case you have any. This is how I handled it.

    Hopefully you have a ProductViewModel:

    public class ProductViewModel
    {
        [Key]
        public string ID { get; set; }
        public string Name { get; set; }
    }
    

    I have dependency injection/repository framework where I call a function to grab my data. Using your post as an example, in your Controller function call, it would look like this:

    int categoryID = 1;
    var prods = repository.GetProducts(categoryID);
    

    In the repository class:

    public IEnumerable<ProductViewModel> GetProducts(int categoryID)
    {
       List<ProductViewModel> lstPVM = new List<ProductViewModel>();
    
       var anonymousObjResult = from p in db.Products
                                where p.CategoryID == categoryID 
                                select new
                                {
                                    CatID = p.CategoryID,
                                    Name = p.Name
                                };
    
            // NOTE: If you have any dates that are nullable and null, you'll need to
            // take care of that:  ClosedDate = (DateTime?)p.ClosedDate ?? DateTime.Now
    
            // If you want a particular date, you have to define a DateTime variable,
            // assign your value to it, then replace DateTime.Now with that variable. You
            // cannot call a DateTime.Parse there, unfortunately. 
            // Using 
            //    new Date("1","1","1800"); 
            // works, though. (I add a particular date so I can edit it out later.)
    
            // I do this foreach below so I can return a List<ProductViewModel>. 
            // You could do: return anonymousObjResult.ToList(); here
            // but it's not as clean and is an anonymous type instead of defined
            // by a ViewModel where you can control the individual field types
    
            foreach (var a in anonymousObjResult)
            {                
                ProductViewModel pvm = new ProductViewModel();
                pvm.ID = a.CatID;  
                pvm.Name = a.Name;
                lstPVM.Add(rvm);
            }
    
            // Obviously you will just have ONE item there, but I built it 
            // like this so you could bring back the whole table, if you wanted
            // to remove your Where clause, above.
    
            return lstPVM;
        }
    

    Back in the controller, you do:

     List<ProductViewModel> lstProd = new List<ProductViewModel>();
    
     if (prods != null) 
     {
        // For setting the dates back to nulls, I'm looking for this value:
        // DateTime stdDate = DateTime.Parse("01/01/1800");
    
        foreach (var a in prods)
        {
            ProductViewModel o_prod = new ReportViewModel();
            o_prod.ID = a.ID;
            o_prod.Name = a.Name;
           // o_prod.ClosedDate = a.ClosedDate == stdDate ? null : a.ClosedDate;
            lstProd.Add(o_prod);
        }
    }
    return View(lstProd);  // use this in your View as:   @model IEnumerable<ProductViewModel>
    
    0 讨论(0)
  • 2020-11-21 06:41

    Another simple way :)

    public IQueryable<Product> GetProducts(int categoryID)
    {
        var productList = db.Products
            .Where(p => p.CategoryID == categoryID)
            .Select(item => 
                new Product
                {
                    Name = item.Name
                })
            .ToList()
            .AsQueryable(); // actually it's not useful after "ToList()" :D
    
        return productList;
    }
    
    0 讨论(0)
  • 2020-11-21 06:41

    You can use this and it should be working --> You must use toList before making the new list using select:

    db.Products
        .where(x=>x.CategoryID == categoryID).ToList()
        .select(x=>new Product { Name = p.Name}).ToList(); 
    
    0 讨论(0)
  • 2020-11-21 06:42

    In response to the other question which was marked as duplicate (see here) I figured out a quick and easy solution based on the answer of Soren:

    data.Tasks.AddRange(
        data.Task.AsEnumerable().Select(t => new Task{
            creator_id   = t.ID,
            start_date   = t.Incident.DateOpened,
            end_date     = t.Incident.DateCLosed,
            product_code = t.Incident.ProductCode
            // so on...
        })
    );
    data.SaveChanges();
    

    Note: This solution only works if you have a navigation property (foreign key) on the Task class (here called 'Incident'). If you don't have that, you can just use one of the other posted solutions with "AsQueryable()".

    0 讨论(0)
  • 2020-11-21 06:45

    You can solve this by using Data Transfer Objects (DTO's).

    These are a bit like viewmodels where you put in the properties you need and you can map them manually in your controller or by using third-party solutions like AutoMapper.

    With DTO's you can :

    • Make data serialisable (Json)
    • Get rid of circular references
    • Reduce networktraffic by leaving properties you don't need (viewmodelwise)
    • Use objectflattening

    I've been learning this in school this year and it's a very useful tool.

    0 讨论(0)
  • 2020-11-21 06:45

    only add AsEnumerable() :

    public IQueryable<Product> GetProducts(int categoryID)
    {
        return from p in db.Products.AsEnumerable()
               where p.CategoryID== categoryID
               select new Product { Name = p.Name};
    }
    
    0 讨论(0)
提交回复
热议问题