Entity Framework - Selecting specific columns

此生再无相见时 提交于 2019-12-06 16:00:18

问题


I have a successful query that links two tables with a where and orderby clause, but I wanted to add to just select specific columns instead of getting everything back.

PART 1 When I attempt this I get syntax errors on the orderby line, if I remove the orderby line the syntax errors move to the where line.

Error 3 Cannot implicitly convert type 'System.Linq.IOrderedQueryable' to 'System.Linq.IQueryable'. An explicit conversion exists (are you missing a cast?)

            IQueryable<VendorProfile> query = _db.VendorProfiles
            .Include("VendorCategories")
            .Include("VendorsSelected")
            .Select(s => new  { s.ProfileID, s.Name, s.CompanyName, s.City, s.State, s.DateCreated, s.VendorsSelected, s.VendorCategories })
            .Where(x => x.VendorsSelected.Select(s => s.UserName).Contains(HttpContext.Current.User.Identity.Name))
            .OrderBy(x => x.DateCreated);

       if (criteria.name != string.Empty)
            query = query.Where(v => v.Name.Contains(criteria.name));
        if (criteria.company != string.Empty)
            query = query.Where(v => v.CompanyName.Contains(criteria.company));
        if (criteria.startDate != null && criteria.endDate != null)
            query = query.Where(v => v.DateCreated > criteria.startDate && v.DateCreated < criteria.endDate);
        if (criteria.categories != null && !criteria.categoryMatchAll)
            query = query.Where(v => criteria.categories.AsQueryable().Any(cat => v.VendorCategories.Select(vendCat => vendCat.CategoryID).Contains(cat)));
        if (criteria.categories != null && criteria.categoryMatchAll)
            query = query.Where(v => criteria.categories.AsQueryable().All(cat => v.VendorCategories.Select(vendCat => vendCat.CategoryID).Contains(cat)));
        if (criteria.minorityType != null)
            query = query.Where(v => v.MinotiryOwned == criteria.minorityType);
        if (criteria.diversityClass != null)
            query = query.Where(v => v.DiversityClassification == criteria.diversityClass);

        return query.ToList();

PART 2 I also wanted to know if I could extract the selected columns into a view model class, so I tired this and I get same results as above on the orderby line

Error 4 Cannot implicitly convert type 'System.Linq.IOrderedQueryable' to 'System.Linq.IQueryable'. An explicit conversion exists (are you missing a cast?)


回答1:


ANSWER

I think you helped me stumble upon the fact that the types don't match. Making the IQueryable type and the select new type and the return type the SAME makes the syntax happy. Using var does not like.

public IEnumerable<BrowseVendorModel> SearchVendors(CustomSearchModel criteria)
{
    IQueryable<BrowseVendorModel> query = _db.VendorProfiles
        .Include("VendorCategories")
        .Include("VendorsSelected")
        .Select(s => new BrowseVendorModel
        {
            ProfileID = s.ProfileID,
            Name = s.Name,
            CompanyName = s.CompanyName,
            City = s.City,
            State = s.State,
            DateCreated = s.DateCreated,
            VendorsSelected = s.VendorsSelected,
            VendorCategories = s.VendorCategories
        })
        .Where(x => x.VendorsSelected.Select(s => s.UserName).Contains(HttpContext.Current.User.Identity.Name))
        .OrderBy(x => x.DateCreated);

    if (criteria.name != string.Empty)
        query = query.Where(v => v.Name.Contains(criteria.name));
    if (criteria.company != string.Empty)
        query = query.Where(v => v.CompanyName.Contains(criteria.company));
    if (criteria.startDate != null && criteria.endDate != null)
        query = query.Where(v => v.DateCreated > criteria.startDate && v.DateCreated < criteria.endDate);
    if (criteria.categories != null && !criteria.categoryMatchAll)
        query = query.Where(v => criteria.categories.AsQueryable().Any(cat => v.VendorCategories.Select(vendCat => vendCat.CategoryID).Contains(cat)));
    if (criteria.categories != null && criteria.categoryMatchAll)
        query = query.Where(v => criteria.categories.AsQueryable().All(cat => v.VendorCategories.Select(vendCat => vendCat.CategoryID).Contains(cat)));
    if (criteria.minorityType != null)
        query = query.Where(v => v.MinotiryOwned == criteria.minorityType);
    if (criteria.diversityClass != null)
        query = query.Where(v => v.DiversityClassification == criteria.diversityClass);

    return query;
}



回答2:


The first example requires var because you are changing the shape of the query by projecting into anonymous type. The second example can either use var or IQueryable<VendorProfileViewModel> because you are changing the shape of the query by projecting into VendorProfileViewModel.



来源:https://stackoverflow.com/questions/15531583/entity-framework-selecting-specific-columns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!