【问题标题】:Entity Framework - Selecting specific columns实体框架 - 选择特定列
【发布时间】:2013-03-20 18:14:43
【问题描述】:

我有一个成功的查询,它使用 where 和 orderby 子句链接两个表,但我想添加以仅选择特定列而不是取回所有内容。

第 1 部分 当我尝试这样做时,我在 orderby 行上出现语法错误,如果我删除 orderby 行,语法错误将移至 where 行。

错误 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();

第 2 部分 我还想知道是否可以将选定的列提取到视图模型类中,所以我厌倦了这个,我在 orderby 行上得到了与上面相同的结果

错误 4 无法将类型“System.Linq.IOrderedQueryable”隐式转换为“System.Linq.IQueryable”。存在显式转换(您是否缺少演员表?)

【问题讨论】:

  • var代替IQueryable&lt;VendorProfile&gt;?
  • @Pawel 不确定我可以,该查询后面有几个选择性的 where 子句(添加到 OP)。您能否为上述代码提出另一个可行的解决方案?
  • 为什么?如果您显式设置类型并且根据您返回的类型无效,则 var 只会让编译器推断出正确的类型。您可以将鼠标悬停在var 上以查看该类型的真正含义。目前,如果您有一个返回字节的函数,但您将结果分配给字符串变量(string myVal = GetByte();),如果您使用var myVal = GetByte();,编译器将知道myVal 应该是字节并将其编译为字节多变的。换句话说,在运行时它总是强类型的,但在编译时你要求编译器做脏活。
  • 也许您想将 ANSWER 部分移至答案并将其标记为已接受?

标签: asp.net-mvc-4 entity-framework-5


【解决方案1】:

回答

我认为您帮助我发现了类型不匹配的事实。使 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;
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 谢谢。我有同样的问题,因为上面 orderby 子句下方的所有 where 子句都会给出错误,因为它们取决于 IQueryable。还有另一种方法可以让我同时构建查询和选择字段吗?
    • 但是你还有IQueryable&lt;VendorProfileViewModel&gt;。如果视图模型包含您在 where 子句中使用的那些字段,它应该可以正常工作。
    • 我想你帮我发现了类型不匹配的事实。将 IQueryable 类型和选择新类型都设置为 VendorProfileViewModel 会使语法变得愉快。使用 var 不喜欢。但是返回的视图页面仍然存在问题。
    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多