The entity cannot be constructed in a LINQ to Entities query

前端 未结 14 2028
失恋的感觉
失恋的感觉 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:46

    If you are using Entity framework, then try removing property from DbContext which uses your complex model as Entity I had same problem when mapping multiple model into a viewmodel named Entity

    public DbSet<Entity> Entities { get; set; }
    

    Removing the entry from DbContext fixed my error.

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

    if you are Executing Linq to Entity you can't use the ClassType with new in the select closure of query only anonymous types are allowed (new without type)

    take look at this snippet of my project

    //...
    var dbQuery = context.Set<Letter>()
                    .Include(letter => letter.LetterStatus)
                    .Select(l => new {Title =l.Title,ID = l.ID, LastModificationDate = l.LastModificationDate, DateCreated = l.DateCreated,LetterStatus = new {ID = l.LetterStatusID.Value,NameInArabic = l.LetterStatus.NameInArabic,NameInEnglish = l.LetterStatus.NameInEnglish} })
                                   ^^ without type__________________________________________________________________________________________________________^^ without type
    

    of you added the new keyword in Select closure even on the complex properties you will got this error

    so remove the ClassTypes from new keyword on Linq to Entity queries ,,

    because it will transformed to sql statement and executed on SqlServer

    so when can I use new with types on select closure?

    you can use it if you you are dealing with LINQ to Object (in memory collection)

    //opecations in tempList , LINQ to Entities; so we can not use class types in select only anonymous types are allowed
    var tempList = dbQuery.Skip(10).Take(10).ToList();// this is list of <anonymous type> so we have to convert it so list of <letter>
    
    //opecations in list , LINQ to Object; so we can use class types in select
    list = tempList.Select(l => new Letter{ Title = l.Title, ID = l.ID, LastModificationDate = l.LastModificationDate, DateCreated = l.DateCreated, LetterStatus = new LetterStatus{ ID = l.LetterStatus.ID, NameInArabic = l.LetterStatus.NameInArabic, NameInEnglish = l.LetterStatus.NameInEnglish } }).ToList();
                                    ^^^^^^ with type 
    

    after I executed ToList on query it became in memory collection so we can use new ClassTypes in select

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

    you can add AsEnumerable to your collection like the follow :

    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)
  • 2020-11-21 06:57

    You cannot (and should not be able to) project onto a mapped entity. You can, however, project onto an anonymous type or onto a DTO:

    public class ProductDTO
    {
        public string Name { get; set; }
        // Other field you may need from the Product entity
    }
    

    And your method will return a List of DTO's.

    public List<ProductDTO> GetProducts(int categoryID)
    {
        return (from p in db.Products
                where p.CategoryID == categoryID
                select new ProductDTO { Name = p.Name }).ToList();
    }
    
    0 讨论(0)
  • 2020-11-21 06:58

    There is another way that I found works, you have to build a class that derives from your Product class and use that. For instance:

    public class PseudoProduct : Product { }
    
    public IQueryable<Product> GetProducts(int categoryID)
    {
        return from p in db.Products
               where p.CategoryID== categoryID
               select new PseudoProduct() { Name = p.Name};
    }
    

    Not sure if this is "allowed", but it works.

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

    You can project into anonymous type, and then from it to model type

    public IEnumerable<Product> GetProducts(int categoryID)
    {
        return (from p in Context.Set<Product>()
                where p.CategoryID == categoryID
                select new { Name = p.Name }).ToList()
               .Select(x => new Product { Name = x.Name });
    }
    

    Edit: I am going to be a bit more specific since this question got a lot of attention.

    You cannot project into model type directly (EF restriction), so there is no way around this. The only way is to project into anonymous type (1st iteration), and then to model type (2nd iteration).

    Please also be aware that when you partially load entities in this manner, they cannot be updated, so they should remain detached, as they are.

    I never did completely understand why this is not possible, and the answers on this thread do not give strong reasons against it (mostly speaking about partially loaded data). It is correct that in partially loaded state entity cannot be updated, but then, this entity would be detached, so accidental attempts to save them would not be possible.

    Consider method I used above: we still have a partially loaded model entity as a result. This entity is detached.

    Consider this (wish-to-exist) possible code:

    return (from p in Context.Set<Product>()
            where p.CategoryID == categoryID
            select new Product { Name = p.Name }).AsNoTracking().ToList();
    

    This could also result in a list of detached entities, so we would not need to make two iterations. A compiler would be smart to see that AsNoTracking() has been used, which will result in detached entities, so it could allow us to do this. If, however, AsNoTracking() was omitted, it could throw the same exception as it is throwing now, to warn us that we need to be specific enough about the result we want.

    0 讨论(0)
提交回复
热议问题