在c#中使用LINQ . select时如何维护类型?
本文关键字:何维护 维护 类型 select LINQ | 更新日期: 2023-09-27 18:03:06
我试图返回一组不同的结果,首先使用Substring修剪,但是当我调用"Select"时,它将其转换为匿名类型。我似乎无法得到这个来维护类型"列表"。我只需要返回Select方法中指定的字段。
public List<Facility> GetFacilities() {
var facilities = new List<Facility>();
facilities = _facilityRepository.GetAll().ToList();
var facReturnList =
facilities.Where(x => x.Fac_Name = "Something")
.OrderBy(x => x.Fac_Name).ToList();
var facReturnList2 =
facReturnList.Select(x =>
new { ID = x.Fac_Name.Substring(0, 6),
Fac_Name = x.Fac_Name.Substring(0, 3) })
.Distinct().ToList();
return facReturnList2;
}
我试着在new
之后添加List<Facility>
,但它说这些属性(ID
和Fac_Name
)没有在Facility中定义。
你想用你的结果初始化新的Facility
实例吗?
var facReturnList2 = facReturnList.Select(x => new Facility { ID = // ...
^ concrete type initializer
对编辑的响应:在Select
操作符中,需要指定要初始化的元素的类型,而不是它们的列表。您之前的代码似乎表明Fac_Name
是在Facility
中定义的,但它显然不会在List<Facility>
中定义。
您将获得匿名类型,因为您正在创建它。
.Select(x => new {
如果你不想那样做,就不要那样做。
如果一个现有的类型已经有了你需要的名称和精确的属性,就使用它。如果没有类型具有所需的内容,则创建一个。则可以返回该类型的适当列表或可枚举对象。
.Select(x => new YourDefinedType {
听起来你真正想要的是一个DistinctBy
方法。你想要指定一些方法来指示一个对象是不同的,但你不希望结果是那个选择的集合,你希望最终结果是开始对象。LINQ没有内置DistinctBy
,但实现一个很容易:
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer = null)
{
comparer = comparer ?? EqualityComparer<TKey>.Default;
HashSet<TKey> knownKeys = new HashSet<TKey>(comparer);
foreach (TSource element in source)
{
if (knownKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
使用它你的代码现在可以变成:
public List<Facility> GetFacilities()
{
return _facilityRepository.GetAll()
.Where(x => x.Fac_Name == "Something")
.DistinctBy(x => new
{
ID = x.Fac_Name.Substring(0, 6),
Fac_Name = x.Fac_Name.Substring(0, 3)
})
.OrderBy(x => x.Fac_Name)
.ToList();
}
如果您有一个IQueryable
而不是内存中的数据集,您可以使用GroupBy
来获得相同的行为。在Linq-to-objects中,使用GroupBy
的效率会低很多,但对于查询提供程序来说,它不会因为数据库能够优化而降低效率。
public List<Facility> GetFacilities()
{
return _facilityRepository.GetAll()
.Where(x => x.Fac_Name == "Something")
.OrderBy(x => x.Fac_Name)
.GroupBy(x => new
{
ID = x.Fac_Name.Substring(0, 6),
Fac_Name = x.Fac_Name.Substring(0, 3)
})
.Select(group => group.First())
.ToList();
}
下面的代码指示linq返回一个匿名类型:
.Select(x => new { ID = x.Fac_Name.Substring(0, 6), Fac_Name = x.Fac_Name.Substring(0, 3) }
你需要为你的结果创建一个类
public class Result{
public string ID { get;set; }
public string Fac_Name { get; set; }
}
//Then do
.Select(x => new Result { ID = x.Fac_Name.Substring(0, 6), Fac_Name = x.Fac_Name.Substring(0, 3) }
这确保您只返回您需要的信息