【问题标题】:C# - IQueryable query how to select? [duplicate]C# - IQueryable 查询如何选择? [复制]
【发布时间】:2017-08-09 07:18:38
【问题描述】:
IQueryable<ImportNameValidation> query = entities.ImportNameValidation
    .Where(y => y.FirstName == searchedName)
    .Where(x => x.NameType == comboValue);

List<ImportNameValidation> ResultValues = query.ToList();  

在这个查询中,我得到了 6 列,但我只需要其中的 3 列,如何使用 select 方法只获取我需要的那些列? 是不是有点像

.Select(t => t.FirstName, u => u.Name, i => i.NameCode);

我在 SQL 中真正想要的不是“选择 *”,而是“选择 NameCode、Name、FirstName”,但我需要它作为 IQueryable。

【问题讨论】:

  • entities.ImportNameValidation.Where(y => y.FirstName == searchedName).Where(x => x.NameType == comboValue).Select(t => new { t.FirstName, t .Name,t.Remarks,t.NameType});我收到一个错误,告诉我我错过了演员请参阅错误:严重代码描述项目文件行抑制状态错误 CS0266 无法隐式转换类型'System.Linq.IQueryable >' 到 'System.Linq.IQueryable'。存在显式转换(您是否缺少演员表?)

标签: c# linq iqueryable


【解决方案1】:

要选择特定的列,您需要投影到具有这些属性(匿名或自定义)的对象

.Select(t => new { t.FirstName, t.Name, t.NameCode })

此外,您可以将两个 where 条件放在同一个谓词中:

entities.ImportNameValidation
        .Where(y => y.FirstName == searchedName && y.NameType == comboValue)
        .Select(t => new { t.FirstName, t.Name, t.NameCode })    

或者在查询语法中:

from item in entities.ImportNameValidation
where item.FirstName == searchedName && item.NameType == comboValue   
select new { item.FirstName, item.Name, item.NameCode }

由于集合中的项目不再是 ImportNameValidation 类型,因此您不能将其分配给 List&lt;ImportNameValidation&gt;。为此,将投影到包含 3 个属性的自定义 DTO 对象(您不能投影到映射类型 - 会导致错误):

List<ImportNameValidationDTO> result = entities.ImportNameValidation
    .Where(y => y.FirstName == searchedName && y.NameType == comboValue)
    .Select(t => new ImportNameValidationDTO { t.FirstName, t.Name, t.NameCode })
    .ToList();

【讨论】:

  • 收到此错误:严重代码描述项目文件行抑制状态错误 CS0266 无法将类型“System.Linq.IQueryable>”隐式转换为“ System.Linq.IQueryable'。存在显式转换(您是否缺少演员表?)
  • @XxXIbbeXxX - 请参阅我回答的最后一部分以了解原因。同样对于该错误,还有许多以前的 SO 问题。问题是您将上述查询的结果分配给不同类型的集合
  • 我什至尝试了最后一个建议并得到以下结果:严重性代码描述项目文件行抑制状态错误 CS0246 找不到类型或命名空间名称“ImportNameValidationDTO”(您是否缺少 using 指令或程序集参考?)
  • @XxXIbbeXxX - 请努力解决您的问题。 ImportNameValidationDTO 尚不存在。您需要创建它。
  • @XxXIbbeXxX - 你成功了吗?
【解决方案2】:

简单使用匿名类型:

.Select(t => new { t.FirstName, t.Name, t.NameCode})

【讨论】:

  • 请注意,这不再是ImportNameValidation的类型
【解决方案3】:

要将其转换为相同对象类型的列表,首先将数据获取为可枚举。

List<ImportNameValidation> ResultValues = query.AsEnumerable().Select(t => new ImportNameValidation { t.FirstName, t.Name, t.NameCode })  ;  

【讨论】:

  • 这里不需要 AsEnumerable。
  • @TravisJ 使用相同的域类型会导致问题。因此,如果您需要将数据投影到域实体中,则需要作为可枚举的。这里就是这种情况。
  • AsEnumerable 将导致整个查询被拉入内存,并抹去仅选择字段子集的收益。
  • @TravisJ 是的,但是由于域模型,不添加 AsEnumerable 将不允许生成列表。因此,要么使用 ViewModel,要么您需要先提取数据。如果我错了,请告诉我。
  • 我不明白为什么域模型会阻止此查询完成。顺便说一句,我没有对此表示反对,我认为这应该可行(没有 AsEnumerable)。例如,请参见此处:dotnetfiddle.net/KdrqtJ。这应该可以正常工作。
猜你喜欢
  • 2021-10-15
  • 2014-12-03
  • 2013-03-22
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多