2013-03-20 114 views
1

我有一个成功的查询,它将两个表与where和orderby子句链接起来,但我想添加到只选择特定的列而不是将所有的东西都回来。实体框架 - 选择特定列

第1部分 当我尝试这样做时,如果我删除orderby行的语法错误移动到where行,我会在orderby行上得到语法错误。

错误3不能将类型'System.Linq.IOrderedQueryable'隐式转换为'System.Linq.IQueryable'。一个显式转换存在(是否缺少强制转换?)

  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 我也想知道如果我能提取选中的列到视图模型类,所以我厌倦了这个,我也得到相同的结果。上面的命令行

错误4不能将类型'System.Linq.IOrderedQueryable'隐式转换为'System.Linq.IQueryable'。存在明确的转换(您是否缺少演员?)

+0

使用'var'而不是'IQueryable '? – Pawel 2013-03-20 18:23:03

+0

@Pawel不知道我可以,有几个选择性的子句后面的查询(添加到OP)。你能否为上述代码提出另一个可行的解决方案? – SQLGrinder 2013-03-20 18:28:57

+0

为什么? var只是让编译器推断出正确的类型,如果你明确地设置类型并且类型根据你返回的内容是无效的。你可以将鼠标悬停在'var'上来查看类型究竟是什么。目前它就好像你有一个返回字节的函数,但是如果你使用'var myVal = GetByte();''编译器会知道myVal('string myVal = GetByte '应该是字节,并将它编译为一个字节变量。换句话说,在运行时,它将始终是强类型的,但是在编译时你要求编译器完成肮脏的工作。 – Pawel 2013-03-20 18:42:23

回答

1

ANSWER

我想你帮我偶然发现的事实,类型不匹配。使用IQueryable类型和选择新类型以及返回类型SAME使语法变得愉快。使用var不喜欢。

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; 
} 
0

第一个示例需要var,因为您要通过投影到匿名类型来更改查询的形状。第二个示例可以使用varIQueryable<VendorProfileViewModel>,因为您要通过投影到VendorProfileViewModel来更改查询的形状。

+0

Thx。我有同样的问题,因为所有where子句在orderby子句下面给出的错误依赖于IQueryable。有没有另外一种方法可以同时构建查询和选择字段? – SQLGrinder 2013-03-20 20:11:31

+0

但你仍然有'IQueryable '。如果视图模型包含您在where子句中使用的那些字段,它应该可以正常工作。 – 2013-03-20 20:13:41

+0

我想你帮助我偶然发现类型不匹配的事实。制作IQueryable类型和选择新类型VendorProfileViewModel都使语法更加开心。使用var不喜欢。但仍然有返回的视图页面的问题。 – SQLGrinder 2013-03-20 21:09:31